c rsa java_通过网络将RSA公钥从C发送到Java

我试图通过网络发送RSA公钥,从用c编写的服务器发送到用

Java编写的客户端.当客户端收到模数时,它应该使用模数和服务器也在使用的公共指数F4重新创建RSA密钥.

以下是服务器生成和发送密钥的方式:

//Generate RSA key in C

RSA *rsa;

int bits = 1024;

unsigned long exp = RSA_F4;

BIGNUM *bn;

BIGNUM *MyModPubKey;

bn = BN_new();

BN_set_word(bn, exp);

rsa = RSA_new();

RSA_generate_key_ex(rsa, bits, bn, NULL);

MyModPubKey = rsa->n;

//Send RSA modulus in C

unsigned char public_key_Mod[128];

unsigned char *PubMod;

int PubModLen;

PubMod = (unsigned char *)&public_key_Mod;

PubModLen = BN_bn2bin(MyModPubKey, PubMod);

assert(PubModLen == 128);

send(sd, public_key_Mod, 128, 0);

以下是如何在Java中重新创建密钥.省略了异常处理.

//Read the modulus

byte[] public_key_mod = new byte[128];

is.read(public_key_mod, 0, 128);

//Create BigInteger modulus and exponent

BigInteger RxPubKeyMod = new BigInteger(1, public_key_mod);

BigInteger RxPubKeyExp = RSAKeyGenParameterSpec.F4;

PublicKey RxRsaPubKey = KeyFactory.getInstance("RSA").generatePublic(

new RSAPublicKeySpec(RxPubKeyMod, RxPubKeyExp));

但是,Java中生成的公共RSA密钥与C中的密钥不同.通过打印base64编码的密钥版本验证.

我还在两端打印模数和指数,并验证它们是否相同.这是怎么做到的:

//Java

System.out.println("RxPubKeyExp: " + RxPubKeyExp.toString(16));

System.out.println("RxPubKeyMod: " + RxPubKeyMod.toString(16));

//C

printf("PubKeyExp %s \n", BN_bn2hex(MyModPubKey->e));

printf("PubKeyMod %s \n", BN_bn2hex(MyModPubKey->n));

他们是一样的.

我无法弄清楚为什么这不起作用.我错过了一些重要的事情.复杂因素是我有一个C版本的客户端,它可以正确地重新创建从服务器收到的信息.它可能是BigInteger用Java签名的东西,但我也尝试插入额外的前导0x00并将bytearray扩展为129字节,结果相同(生成相同的密钥).

拜托,我完全卡住了.

谢谢

更新:

以下是C服务器的示例输出:

PubKeyExp 010001

PubKeyMod A8CB09C2B84762A8C822F18C9CA48036E0D9988C9D8625BF5F2DF16FDEEC92D018863E129C0AE89EB0C344FD32DFF419548C39BB41A867293BC4BD84A1ECAEB0D723EEA97BD2651AF8BD56B2C97D38A39111A0C48894BC034371C2EDB96F1E2E9CDDA9B16DFBE80580ADFDA3853445120F7429AD60300E31254864041210B0BB

PublicKey -----BEGIN RSA PUBLIC KEY-----

MIGJAoGBAKjLCcK4R2KoyCLxjJykgDbg2ZiMnYYlv18t8W/e7JLQGIY+EpwK6J6w

w0T9Mt/0GVSMObtBqGcpO8S9hKHsrrDXI+6pe9JlGvi9VrLJfTijkRGgxIiUvAND

ccLtuW8eLpzdqbFt++gFgK39o4U0RRIPdCmtYDAOMSVIZAQSELC7AgMBAAE=

-----END RSA PUBLIC KEY-----

它以这种方式打印:

printf("PubKeyExp %s \n", BN_bn2hex(MyModPubKey->e));

printf("PubKeyMod %s \n", BN_bn2hex(MyModPubKey->n));

FILE *fp;

char *pubKeyString;

pubKeyString = calloc(1, 512);

if(!(fp = fmemopen(pubKeyString, 512, "w"))) {

exit(1);

}

PEM_write_RSAPublicKey(fp, pubKey);

fflush(fp);

fclose(fp);

printf("PublicKey %s \n",pubKeyString);

其中pubKey = rsa如上所述

以下是Java服务器的示例输出:

RxPubKeyExp: 10001

RxPubKeyMod: a8cb09c2b84762a8c822f18c9ca48036e0d9988c9d8625bf5f2df16fdeec92d018863e129c0ae89eb0c344fd32dff419548c39bb41a867293bc4bd84a1ecaeb0d723eea97bd2651af8bd56b2c97d38a39111a0c48894bc034371c2edb96f1e2e9cdda9b16dfbe80580adfda3853445120f7429ad60300e31254864041210b0bb

RxRsaPubKey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCoywnCuEdiqMgi8YycpIA24NmYjJ2GJb9fLfFv3uyS0BiGPhKcCuiesMNE/TLf9BlUjDm7QahnKTvEvYSh7K6w1yPuqXvSZRr4vVayyX04o5ERoMSIlLwDQ3HC7blvHi6c3amxbfvoBYCt/aOFNEUSD3QprWAwDjElSGQEEhCwuwIDAQAB

它以这种方式打印:

System.out.println("RxPubKeyExp: " + RxPubKeyExp.toString(16));

System.out.println("RxPubKeyMod: " + RxPubKeyMod.toString(16));

String RxRsaPubKeyChar = Base64.encodeToString(RxRsaPubKey.getEncoded(), Base64.DEFAULT);

System.out.println("RxRsaPubKey: " + RxRsaPubKeyChar);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java和.NET中,RSA密钥的存储格式不同,因此需要进行格式转换才能实现密钥的交换。下面是Java和.NET之间RSA密钥格式转换的详细步骤。 1. 将Java中的公钥格式转换为.NET中的公钥格式: Java中的公钥格式为X.509证书格式,需要将其转换为XML格式。具体步骤如下: ``` KeyFactory keyFactory = KeyFactory.getInstance("RSA"); X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes); PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); StringWriter sw = new StringWriter(); XmlWriter xw = XmlWriter.Create(sw); RSAParameters parameters = new RSAParameters(); parameters.Modulus = publicKey.getModulus().toByteArray(); parameters.Exponent = publicKey.getPublicExponent().toByteArray(); xw.WriteStartElement("RSAKeyValue"); xw.WriteElementString("Modulus", Convert.ToBase64String(parameters.Modulus)); xw.WriteElementString("Exponent", Convert.ToBase64String(parameters.Exponent)); xw.WriteEndElement(); xw.Flush(); ``` 2. 将Java中的私钥格式转换为.NET中的私钥格式: Java中的私钥格式为PKCS#8格式,需要将其转换为XML格式。具体步骤如下: ``` KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes); PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec); StringWriter sw = new StringWriter(); XmlWriter xw = XmlWriter.Create(sw); RSAParameters parameters = new RSAParameters(); parameters.Modulus = privateKey.getModulus().toByteArray(); parameters.D = privateKey.getPrivateExponent().toByteArray(); parameters.P = privateKey instanceof RSAPrivateCrtKey ? ((RSAPrivateCrtKey)privateKey).getPrimeP().toByteArray() : null; parameters.Q = privateKey instanceof RSAPrivateCrtKey ? ((RSAPrivateCrtKey)privateKey).getPrimeQ().toByteArray() : null; parameters.DP = privateKey instanceof RSAPrivateCrtKey ? ((RSAPrivateCrtKey)privateKey).getPrimeExponentP().toByteArray() : null; parameters.DQ = privateKey instanceof RSAPrivateCrtKey ? ((RSAPrivateCrtKey)privateKey).getPrimeExponentQ().toByteArray() : null; parameters.InverseQ = privateKey instanceof RSAPrivateCrtKey ? ((RSAPrivateCrtKey)privateKey).getCrtCoefficient().toByteArray() : null; xw.WriteStartElement("RSAKeyValue"); xw.WriteElementString("Modulus", Convert.ToBase64String(parameters.Modulus)); xw.WriteElementString("Exponent", Convert.ToBase64String(privateKey.getPublicExponent().toByteArray())); xw.WriteElementString("D", Convert.ToBase64String(parameters.D)); xw.WriteElementString("P", Convert.ToBase64String(parameters.P)); xw.WriteElementString("Q", Convert.ToBase64String(parameters.Q)); xw.WriteElementString("DP", Convert.ToBase64String(parameters.DP)); xw.WriteElementString("DQ", Convert.ToBase64String(parameters.DQ)); xw.WriteElementString("InverseQ", Convert.ToBase64String(parameters.InverseQ)); xw.WriteEndElement(); xw.Flush(); ``` 3. 将.NET中的公钥格式转换为Java中的公钥格式: .NET中的公钥格式为XML格式,需要将其转换为X.509证书格式。具体步骤如下: ``` XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlPublicKey); RSAParameters parameters = new RSAParameters(); parameters.Modulus = Convert.FromBase64String(doc.SelectSingleNode("//Modulus").InnerText); parameters.Exponent = Convert.FromBase64String(doc.SelectSingleNode("//Exponent").InnerText); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.ImportParameters(parameters); RSACryptoServiceProvider rsaPublic = new RSACryptoServiceProvider(); rsaPublic.ImportParameters(rsa.ExportParameters(false)); byte[] x509publicKey = rsaPublic.ExportCspBlob(false); ``` 4. 将.NET中的私钥格式转换为Java中的私钥格式: .NET中的私钥格式为XML格式,需要将其转换为PKCS#8格式。具体步骤如下: ``` XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlPrivateKey); RSAParameters parameters = new RSAParameters(); parameters.Modulus = Convert.FromBase64String(doc.SelectSingleNode("//Modulus").InnerText); parameters.D = Convert.FromBase64String(doc.SelectSingleNode("//D").InnerText); parameters.P = Convert.FromBase64String(doc.SelectSingleNode("//P").InnerText); parameters.Q = Convert.FromBase64String(doc.SelectSingleNode("//Q").InnerText); parameters.DP = Convert.FromBase64String(doc.SelectSingleNode("//DP").InnerText); parameters.DQ = Convert.FromBase64String(doc.SelectSingleNode("//DQ").InnerText); parameters.InverseQ = Convert.FromBase64String(doc.SelectSingleNode("//InverseQ").InnerText); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.ImportParameters(parameters); byte[] pkcs8privateKey = rsa.ExportPkcs8PrivateKey(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值