.Net BouncyCastle.CryptoExt
Java bcprov-ext-jdk15on-150.jar
里面的RSA可以通用
.net里面我已经用BouncyCastle.CryptoExt了,java那里还是java自带的,这样可以吗?或者还有什么别的解决方案吗?
@liut2010:
Java自带的不行,要用对应Java的bcprov-ext-jdk15on-150.jar
也是BouncyCastle团队写的
@liut2010: 你好,请问你在C# 里面怎么使用 BouncyCastle.Crypto 开发包 用MD5withRas 加密啊?
多方接口给出了 私钥和公钥。
把 xml 中那个节点的值读取出来就是行了。
我就是想知道是以什么方式读xml节点的,是直接拿过来用吗,肯定不行,还是需要怎么处理呢,因为是要把公钥传送给java系统的
@liut2010: 你把你以 XML 形式导出的公钥的 XML 文件内容贴出来。
@Launcher: 公钥
<RSAKeyValue>
<Modulus>pz16OYO4Vrt10botXZDEg3CEoRUSpqG60r5ObAFmB/qHX2S6q4Nth7GrGTg7I24r3rAznOF4STapVa/mTI1KXcpr3gjAxiRCS2ysG+469OkFlzltOW9yE0Zc8OJ1ak6Ah0svOQlCNm6HmxbA9HnYPmBFaSAf9U17mFA3xM9ebAM=</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
私钥
<RSAKeyValue>
<Modulus>pz16OYO4Vrt10botXZDEg3CEoRUSpqG60r5ObAFmB/qHX2S6q4Nth7GrGTg7I24r3rAznOF4STapVa/mTI1KXcpr3gjAxiRCS2ysG+469OkFlzltOW9yE0Zc8OJ1ak6Ah0svOQlCNm6HmxbA9HnYPmBFaSAf9U17mFA3xM9ebAM=</Modulus>
<Exponent>AQAB</Exponent>
<P>0xM8XHskHVmsFiypJsrUa7ruJ7uOfmnRiIa7/TxN+fRkv7tUzjcxqE2glx8JtJb8TcJvXuxj3hVxL835XNwlIQ==</P>
<Q>ytXSibR3sw7TQxqjfEOgwtoTaofnRcaQE8+MsOJti5qh7Yk6nRFGHPBNVS3fYSZIe0J7IFA10n3Nbe/x2xHIow==</Q>
<DP>DEBllIihRALcdj0JZHMJeWdUQ4Ijdzr1KpOHfd9uNz/0SRy6g224uCgpVhw7F/xbkLfkdwIJme5sr3WpL7angQ==</DP>
<DQ>DP4hXFzJBhk/Ax9jtYQHejPJ5psJ/3g2pm43DuWSKs0e7j5KGOGQYi4qZfhoRKrVHcAmbu10ZSVV0WL7VRMQjQ==</DQ>
<InverseQ>zCllAjpv5lNCf+jEHP0vtGj0+eNJBuRXGodwqzF3RiXlI9IWF7zhvuv0RgGu1YkWqHQiIAnUt4f9sEPxqqnJxg==</InverseQ>
<D>N7jYHImyxdM38mUh8Gbn0xOOXU10JWkFomoeHwZoRIhIypP5TmQ//lJIO+LscWWn4E69I6xMM7iuuwocpaz99bAu9W0DCSNfEgv0Ls1RSk2IbZSA6d0JynRoO2sU5q+1J7F2GoW0TL6C+duHRrRX+IlYx9g7aK7jC9/XkZRPuwE=</D>
</RSAKeyValue>
@liut2010:
pz16OYO4Vrt10botXZDEg3CEoRUSpqG60r5ObAFmB/qHX2S6q4Nth7GrGTg7I24r3rAznOF4STapVa/mTI1KXcpr3gjAxiRCS2ysG+469OkFlzltOW9yE0Zc8OJ1ak6Ah0svOQlCNm6HmxbA9HnYPmBFaSAf9U17mFA3xM9ebAM=
这就是公钥的 BASE64 编码后的字符串。
@Launcher: 按照你的方法,把这个字符串用Convert.FromBase64String转换为字节,然后从网上找到一个开源的BigInteger类,用new BigInteger()构造一个大整数,再把这个大整数转换16进制字符串发送到另一方,还是不行,中间有什么问题吗?
@liut2010: 看下这个结构:
http://msdn.microsoft.com/zh-cn/library/system.security.cryptography.rsaparameters(v=vs.110).aspx
public class RSAKeyValue { public string Modulus { get; set; } public string Exponent { get; set; } public string P { get; set; } public string Q { get; set; } public string DP { get; set; } public string DQ { get; set; } public string InverseQ { get; set; } public string D { get; set; } } class Program { static void Main(string[] args) { RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(); XmlSerializer formater = new XmlSerializer(typeof(RSAKeyValue)); StringReader sr = new System.IO.StringReader( rsaProvider.ToXmlString(true)); RSAKeyValue rsaKey = (RSAKeyValue)formater.Deserialize(sr); // 字符串形式 RSAParameters rsaParameters = rsaProvider.ExportParameters(true); // 字节数组形式 } }
公钥是 Modules 和 Exponent 。
@Launcher:
1 RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(); 2 3 XmlSerializer formater = new XmlSerializer(typeof(RSAKeyValue)); 4 StringReader sr = new System.IO.StringReader(rsaProvider.ToXmlString(true)); 5 6 RSAKeyValue rsaKey = (RSAKeyValue)formater.Deserialize(sr); // 字符串形式 7 RSAParameters rsaParameters = rsaProvider.ExportParameters(true); // 字节数组形式 8 9 BigInteger bi_e = new BigInteger(new BigInteger(rsaParameters.Exponent).ToHexString(), 16); 10 BigInteger bi_d = new BigInteger(new BigInteger(rsaParameters.D).ToHexString(), 16); 11 BigInteger bi_n = new BigInteger(new BigInteger(rsaParameters.Modulus).ToHexString(), 16); 12 13 14 string val = "hello"; 15 BigInteger bi_data = new BigInteger(Encoding.Default.GetBytes(val), 5); 16 BigInteger bi_encrypted = bi_data.modPow(bi_e, bi_n); 17 BigInteger bi_decrypted = bi_encrypted.modPow(bi_d, bi_n); 18 19 string temp = Encoding.Default.GetString(bi_decrypted.getBytes());
这个是我写的加密和解密,最后的temp和val是相等的,我就是想知道那个公钥表示成16进制的字符串怎么写?
@liut2010: 你把字节数组 Modulus 转换成 16 进制字符串就行了,Exponent 是公钥指数,双方如果没有约定的话,你可以把 Exponent 和 Modulus 连接起来,然后转换成 16 进制字符串,对方拿到后需要读取前 3 个字节得到 Exponent,然后剩下的就是 Modulus 。
@liut2010: 上面个好厉害,给个简单版本的吧:
byte[] data = {214,46,220,83,160,73,40,39,201,155};
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
@Launcher:
1 string m = new BigInteger(rsaParameters.Modulus).ToHexString(); 2 string exp = new BigInteger(rsaParameters.Exponent).ToHexString();
根据你的提示在上面的代码中加入这两行,就是把Modulus和Exponent转为16进制字符串,是m+exp还是exp+m,我都试了下,传到java那里还是不行呢?
@liut2010: 没有个标准真难讨论,要不咱两这样来说吧,你问他,他要的公钥是 PKCS1 规范下的吗?密钥长度是多少?
http://msdn.microsoft.com/zh-cn/library/system.security.cryptography.rsaparameters(v=vs.110).aspx
你就对着这个链接里同 PKCS #1 的相互解释来问他。也就是他要的到底是 PKCS #1 对应字段的哪个?
@Launcher: 可能是我问的方式不对,换个思路试下吧
1 string publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQClrBWWPtAD3KsZvgyHYh5u2yTsuX6iI+vI+aGb7xBKdc8r9Dliuyc7a5thUEaJI8ZHDLXeDp5WnEJmW6a3/XKnvQNrAr6iIrtqvduIaFCgWLb2ZioBR1ODKe2o3dklsizsj66LIz9TFWL0hb7MXWQDEAd+IK4BaQ+OAr9vBtF7dwIDAQAB"; 2 3 4 string privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKWsFZY+0APcqxm+DIdiHm7bJOy5fqIj68j5oZvvEEp1zyv0OWK7Jztrm2FQRokjxkcMtd4OnlacQmZbprf9cqe9A2sCvqIiu2q924hoUKBYtvZmKgFHU4Mp7ajd2SWyLOyProsjP1MVYvSFvsxdZAMQB34grgFpD44Cv28G0Xt3AgMBAAECgYAQw+FLWv/h5CrMaBcMfDloLnUGH59Y+RmbNOfNx9t2LYXRhN1pyFaoBLOsnVsF9cDS385nskMDsLxnb07nv5YiiPDf9b6/ge27Yvgzss6wqiARiuHr76ArJMwPTz4FcIBsM2qSCbGS3nArns3N7YsvKo0KYMq60w+YV5svIZE+gQJBAPfCfahSiol94z6cLolDHkFsc+4HY01G1fnWLwZo5qzi+jA/k1Q6FeLxlq8itmHAsZclWFq8muBGGZbM1K/ETC8CQQCrLqw/myL/j8Z3Y4higwd2rwnrzb25WcVkT4Uj0QfNKzGHoCqY1w0F24Qree9AxHzK3QQycghvEAo5KtqycYs5AkEA8I/OVG34h7FMwRECelJKATodgiN4PqMlxhQ5yp52Q62LQOep1GEluRnbticdMOLZTCl9lXSFaHeIBwzRAey2DwJBAKBnEZxgYEEclhoVOB0nLn01s5Qzq43c4qwGH3naSvcjfDvcB05EZL2SXpzmmxwTgeQNiftDA0gevZWn5FnFL3ECQBrld2zUNjZrxRCAlH4G/IyzusiHGAeryIh7ztlIuqQ4a4l3RqyMRSeABgpVdjrVFREJp67aH06KoNSPJJK7v9w=";
这两个应该就是java那里base64编码之后的密钥对了,在.net里面怎么使用呢?
@liut2010: 绕了一大圈,看这个吧:http://www.cnblogs.com/adylee/p/3611491.html
@Launcher: 在.net里面生成的modulus和exponent直接给java他们那里,能通用吗?
@liut2010: 能。
@Launcher: 我把m和e给java那里之后,他们可以进行加密,他们把加密后的数据转为16进制字符串发过来,我用.net自带的解密方法的时候,说超过了128位,再网上找了几个方法也试了下,解密出来就开始乱码了,乱码我也查了下,网上的解决方案似乎都没用?
@Launcher: http://www.cnblogs.com/hhh/archive/2011/06/03/2070692.html,看的这个
@liut2010: 请问,你是想问我如何用 C# 写一个 RSA 的解密算法吗?如果是的话,对不起,请你自己打开 OpenSSL 源码,或者使用 OpenSSL 类库,否则的话,请使用 .Net 提供的 RSA 或其派生类。
最简单的方法,看大公司做的,支付宝的支付接口不是有提供代码demo么。
把他们关于rsa加密的Java版本和.Net版本的代码copy出来就可以了。
要学会借鉴。
他们接口都是加密后把加密数据发过去的,我现在是需要把公钥传过去
@liut2010: 公钥私钥是双方约定好的阿。
@graymaster: 是这样的,我这里生成密钥对,把公钥给他们,然后他们用我传送的公钥把数据加密过来,然后我再用私钥进行解密,就是这个传送的过程中,密钥的格式不一致,而且.net和java的rsa加密方式也不一样
@liut2010: 就是支付宝的业务一模一样。。。
公钥私钥都是一个字节数组,不管是XML还是字符串还是编码方式不同,
你只要全转成字节数组,再编码发给另一方就行了
能给一个demo看看吗,我照着你说的做了,还是不行呢?
@liut2010: 这哪儿有什么demo,你是怎么实现的?你两边分别是什么格式知道弄清楚了没现在
该问题的解决方案主要是参考这里http://www.codeproject.com/Articles/25487/Cryptographic-Interoperability-Keys,不过还是非常感谢各位的回答@graymaster,@Nick.Lee,@Launcher,@吴瑞祥
请问你是怎么解决的,可否把方案贴出来。