首页 新闻 会员 周边 捐助

.net rsa 加密解密 与 java 互通

0
悬赏园豆:200 [已解决问题] 解决于 2014-04-23 16:10

在.net中怎么能生成与java中相同的密钥对呢?.net里面用的是xml格式,java是字符串,网上的资料基本都看过了,没有什么合适的,有什么方法或思路可以解决吗,谢过各路大神,如果描述不清楚的话可以在回答里面说下

liut2010的主页 liut2010 | 初学一级 | 园豆:24
提问于:2014-04-16 17:04
< >
分享
最佳答案
0

.Net BouncyCastle.CryptoExt

Java bcprov-ext-jdk15on-150.jar

里面的RSA可以通用

收获园豆:100
Nick.Lee | 菜鸟二级 |园豆:307 | 2014-04-22 12:46

.net里面我已经用BouncyCastle.CryptoExt了,java那里还是java自带的,这样可以吗?或者还有什么别的解决方案吗?

liut2010 | 园豆:24 (初学一级) | 2014-04-22 15:36

@liut2010: 

Java自带的不行,要用对应Java的bcprov-ext-jdk15on-150.jar

也是BouncyCastle团队写的

Nick.Lee | 园豆:307 (菜鸟二级) | 2014-04-22 16:55

@liut2010:  你好,请问你在C# 里面怎么使用 BouncyCastle.Crypto 开发包 用MD5withRas 加密啊?

多方接口给出了 私钥和公钥。

北宫衍 | 园豆:200 (初学一级) | 2015-05-15 15:14
其他回答(5)
0

把 xml 中那个节点的值读取出来就是行了。

收获园豆:80
Launcher | 园豆:45050 (高人七级) | 2014-04-16 17:46

我就是想知道是以什么方式读xml节点的,是直接拿过来用吗,肯定不行,还是需要怎么处理呢,因为是要把公钥传送给java系统的

支持(0) 反对(0) liut2010 | 园豆:24 (初学一级) | 2014-04-17 10:05

@liut2010: 你把你以 XML 形式导出的公钥的 XML 文件内容贴出来。

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-04-17 10:46

@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>

支持(0) 反对(0) liut2010 | 园豆:24 (初学一级) | 2014-04-17 12:24

@liut2010: 

pz16OYO4Vrt10botXZDEg3CEoRUSpqG60r5ObAFmB/qHX2S6q4Nth7GrGTg7I24r3rAznOF4STapVa/mTI1KXcpr3gjAxiRCS2ysG+469OkFlzltOW9yE0Zc8OJ1ak6Ah0svOQlCNm6HmxbA9HnYPmBFaSAf9U17mFA3xM9ebAM=

这就是公钥的 BASE64 编码后的字符串。

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-04-17 13:05

@Launcher: 按照你的方法,把这个字符串用Convert.FromBase64String转换为字节,然后从网上找到一个开源的BigInteger类,用new BigInteger()构造一个大整数,再把这个大整数转换16进制字符串发送到另一方,还是不行,中间有什么问题吗?

支持(0) 反对(0) liut2010 | 园豆:24 (初学一级) | 2014-04-17 14:40

@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 。

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-04-17 15:31

@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进制的字符串怎么写?

 

支持(0) 反对(0) liut2010 | 园豆:24 (初学一级) | 2014-04-17 16:22

@liut2010: 你把字节数组 Modulus 转换成 16 进制字符串就行了,Exponent 是公钥指数,双方如果没有约定的话,你可以把 Exponent 和 Modulus 连接起来,然后转换成 16 进制字符串,对方拿到后需要读取前 3 个字节得到 Exponent,然后剩下的就是 Modulus 。

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-04-17 16:42

@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"));
}

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-04-17 16:47

@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那里还是不行呢?

支持(0) 反对(0) liut2010 | 园豆:24 (初学一级) | 2014-04-17 17:05

@liut2010: 没有个标准真难讨论,要不咱两这样来说吧,你问他,他要的公钥是 PKCS1 规范下的吗?密钥长度是多少?

http://msdn.microsoft.com/zh-cn/library/system.security.cryptography.rsaparameters(v=vs.110).aspx

你就对着这个链接里同 PKCS #1 的相互解释来问他。也就是他要的到底是 PKCS #1 对应字段的哪个?

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-04-17 17:13

@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里面怎么使用呢?

支持(0) 反对(0) liut2010 | 园豆:24 (初学一级) | 2014-04-17 17:16

@liut2010: 绕了一大圈,看这个吧:http://www.cnblogs.com/adylee/p/3611491.html

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-04-17 17:56

@Launcher: 在.net里面生成的modulus和exponent直接给java他们那里,能通用吗?

支持(0) 反对(0) liut2010 | 园豆:24 (初学一级) | 2014-04-18 11:42

@liut2010: 能。

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-04-18 11:44

@Launcher: 我把m和e给java那里之后,他们可以进行加密,他们把加密后的数据转为16进制字符串发过来,我用.net自带的解密方法的时候,说超过了128位,再网上找了几个方法也试了下,解密出来就开始乱码了,乱码我也查了下,网上的解决方案似乎都没用?

支持(0) 反对(0) liut2010 | 园豆:24 (初学一级) | 2014-04-18 13:33

@Launcher: http://www.cnblogs.com/hhh/archive/2011/06/03/2070692.html,看的这个

支持(0) 反对(0) liut2010 | 园豆:24 (初学一级) | 2014-04-18 13:33

@liut2010: 请问,你是想问我如何用 C# 写一个 RSA 的解密算法吗?如果是的话,对不起,请你自己打开 OpenSSL 源码,或者使用 OpenSSL 类库,否则的话,请使用 .Net 提供的 RSA 或其派生类。

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-04-18 13:46
0

最简单的方法,看大公司做的,支付宝的支付接口不是有提供代码demo么。

把他们关于rsa加密的Java版本和.Net版本的代码copy出来就可以了。

要学会借鉴。

收获园豆:10
graymaster | 园豆:7 (初学一级) | 2014-04-17 00:08

他们接口都是加密后把加密数据发过去的,我现在是需要把公钥传过去

支持(0) 反对(0) liut2010 | 园豆:24 (初学一级) | 2014-04-17 10:07

@liut2010: 公钥私钥是双方约定好的阿。

支持(0) 反对(0) graymaster | 园豆:7 (初学一级) | 2014-04-17 11:50

@graymaster: 是这样的,我这里生成密钥对,把公钥给他们,然后他们用我传送的公钥把数据加密过来,然后我再用私钥进行解密,就是这个传送的过程中,密钥的格式不一致,而且.net和java的rsa加密方式也不一样

支持(0) 反对(0) liut2010 | 园豆:24 (初学一级) | 2014-04-17 12:26

@liut2010: 就是支付宝的业务一模一样。。。

支持(0) 反对(0) graymaster | 园豆:7 (初学一级) | 2014-04-17 16:21
0

公钥私钥都是一个字节数组,不管是XML还是字符串还是编码方式不同,

你只要全转成字节数组,再编码发给另一方就行了

收获园豆:10
吴瑞祥 | 园豆:29449 (高人七级) | 2014-04-17 13:55

能给一个demo看看吗,我照着你说的做了,还是不行呢?

支持(0) 反对(0) liut2010 | 园豆:24 (初学一级) | 2014-04-17 14:42

@liut2010: 这哪儿有什么demo,你是怎么实现的?你两边分别是什么格式知道弄清楚了没现在

支持(0) 反对(0) 吴瑞祥 | 园豆:29449 (高人七级) | 2014-04-17 16:03
0

该问题的解决方案主要是参考这里http://www.codeproject.com/Articles/25487/Cryptographic-Interoperability-Keys,不过还是非常感谢各位的回答@graymaster,@Nick.Lee,@Launcher,@吴瑞祥

liut2010 | 园豆:24 (初学一级) | 2014-04-23 16:05
0

请问你是怎么解决的,可否把方案贴出来。

73bull | 园豆:202 (菜鸟二级) | 2015-05-20 11:32
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册