首页 新闻 会员 周边

C# RSA公钥加密对接海信的delphi接口的问题

0
悬赏园豆:200 [已解决问题] 解决于 2016-03-29 12:07

都已经记不得弄了多少天了,哪位大神帮帮忙啊!/(ㄒoㄒ)/~~。身上园豆全部奉上,只盼解决问题,先拜谢了

【获得的公钥】

KEYE:65537
KEYN:20963770985082037258267013644832680819194444170865674109439404719885226241714481879640783348297997948427404211373894962551236372533411432647622255530836353218272251916811821629043426707565400351131213303148172115928391315808665241847484993407632783520603053639514468062034674617971413297279493510927957440275568732809417989268857024667945756452767120447211373511007441264575103012675179769758922918966654874533285783639668932301859385955501408660891072760643889895703821362288397513136466372572877510678561083413134328083977102081885958523282887072436899591195972865308007615085235131433633410539409896249248231311437

【传递参数】

一个XML字符串,字符串长度279

 

【我使用过的方法】

方法1:使用bigInteger分段再计算

 1 List<byte> byteList = new List<byte>();
 2 
 3             int len = data.Length;//明文长度
 4             int len1 = 0;//将明文分成多少段
 5             int blockLen = 0;//每一段长度
 6             string block = "";//存储每一段的明文
 7             string temp = "";//存储密文
 8 
 9             int splitLen = 256 - 11;
10 
11             //计算可以将明文分成多少段
12             if (len % splitLen == 0)
13             {
14                 len1 = len / splitLen;
15             }
16             else
17             {
18                 len1 = len / splitLen + 1;
19             }
20 
21             //给明文加密
22             for (int i = 0; i < len1; i++)
23             {
24                 if (len >= splitLen)
25                 {//明文还能分段
26                     blockLen = splitLen;
27                 }
28                 else
29                 {//明文已经到最后一段了
30                     blockLen = len;
31                 }
32 
33                 block = data.Substring(i * splitLen, blockLen);//取出一段明文用来加密
34                 byte[] oText = System.Text.Encoding.UTF8.GetBytes(block);//将分段明文转换为byte[]
35                 BigInteger biText = new BigInteger(oText);//将分段明文的byte流转换为BigInteger
36                 BigInteger biEnText = BigInteger.ModPow(biText, keye, keyn);//给分段明文加密生成分段密文
37                 //string temp1 = biEnText.ToString("X");//将分段密文转换成二进制
38                 //string temp1 = BitConverter.ToString(biEnText.ToByteArray());
39                 string temp1 = Convert.ToBase64String(biEnText.ToByteArray());
40                 temp += temp1;//加分段密文添加到密文的队列当中
41 
42                 len -= blockLen;//明文长度减去已经加密的分段长度
43 
44 
45                 byteList.AddRange(biEnText.ToByteArray());
46             }
47 
48             byte[] byteArr = byteList.ToArray();
49 
50             return temp;//返回密文
View Code

方法2:使用bigInteger直接计算  m^e mod n

 1 List<byte> byteList = new List<byte>();
 2 
 3             int len = data.Length;//明文长度
 4             int len1 = 0;//将明文分成多少段
 5             int blockLen = 0;//每一段长度
 6             string block = "";//存储每一段的明文
 7             string temp = "";//存储密文
 8 
 9             int splitLen = 256 - 11;
10 
11             //计算可以将明文分成多少段
12             if (len % splitLen == 0)
13             {
14                 len1 = len / splitLen;
15             }
16             else
17             {
18                 len1 = len / splitLen + 1;
19             }
20 
21             byte[] dataBytes = Encoding.UTF8.GetBytes(data);
22             BigInteger dataBigInt = new BigInteger(dataBytes);
23             BigInteger miwenBigInt = BigInteger.ModPow(dataBigInt, keye, keyn);
24 
25             string result = Convert.ToBase64String(miwenBigInt.ToByteArray());
26             //string result = miwenBigInt.ToString();
27             return result;
View Code

方法3:使用RSAParameters、RSACryptoServiceProvider。分段加密RSACryptoServiceProvider.ImportParameters(RSAParameters)

 1 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
 2 
 3             RSAParameters rsaParam = new RSAParameters();
 4 
 5             BigInteger be = BigInteger.Parse(keye);
 6             BigInteger bn = BigInteger.Parse(keyn);
 7 
 8             rsaParam.Exponent = be.ToByteArray();
 9             //rsaParam.Modulus = bn.ToByteArray();
10             List<byte> byteList = new List<byte>(bn.ToByteArray());
11             byteList.Reverse();
12             rsaParam.Modulus = byteList.ToArray();            
13             rsa.ImportParameters(rsaParam);
14 
15             int cellLength = rsaParam.Modulus.Length;
16             int maxLength = cellLength - 12;//计算密文最大长度
17             byte[] dataByte = Encoding.UTF8.GetBytes(data);//将inputParam转换为byte[]
18             int len = dataByte.Length;//inputParam的byte的长度
19             int groupLength = (int)Math.Ceiling(len * 1.00 / maxLength);//计算明文分段长度
20 
21             byte[] result = new byte[groupLength * cellLength];
22 
23             for (int i = 0; i < groupLength; i++)
24             {
25                 int len1 = maxLength < len - maxLength * i ? maxLength : len - maxLength * i;//设置明文分段长度
26                 byte[] inByte = new byte[len1];//定义明文一段byte
27                 Array.Copy(dataByte, maxLength * i, inByte, 0, len1);//获取一段明文byte
28                 byte[] temp = rsa.Encrypt(inByte, false);//加密一段明文
29                 Array.Copy(temp, 0, result, i * cellLength, cellLength);
30             }
31 
32             List<byte> byteResult = new List<byte>(result);
33             byteResult.Reverse();
34             result = byteResult.ToArray();
35             result = removeMSZero(result);
36 
37             string r = Convert.ToBase64String(result);
38             return r;
View Code
水知寒的主页 水知寒 | 初学一级 | 园豆:2
提问于:2016-03-28 10:47
< >
分享
最佳答案
0

 

虽然我点不开你的代码,但是我觉得方法3就行了,至于你的“分段加密”因为看不到代码,不知道什么意思,RSACryptoServiceProvider 支持大于 KEY 长度的数据加密,不用你分段。

收获园豆:200
Launcher | 高人七级 |园豆:45045 | 2016-03-28 16:56

谢谢 @Launcher  ,对方编译了一个dll把加密算法打包进去了,我直接调用他的解决了。

等项目结束了一定要研究透彻,倒是希望给予帮助,谢谢了。

水知寒 | 园豆:2 (初学一级) | 2016-03-29 12:05
其他回答(1)
0

你好,我也遇到这个问题,请问你是用C#调用海信的dll吗

ccczzz | 园豆:202 (菜鸟二级) | 2018-09-02 23:31

我们最后是直接把海信给的RSADLL.dll直接放到bin目录下面,就可以调用了

支持(0) 反对(0) 水知寒 | 园豆:2 (初学一级) | 2018-09-03 09:56

@水知寒: 请问调用有示例代码参考吗?我最近在对接海信的会员接口

支持(0) 反对(0) ccczzz | 园豆:202 (菜鸟二级) | 2018-09-03 12:50

@ccczzz:
加密的是这个,其他的都是接口调用了,就没有粘了
private const string _fileDll = @"RSADLL.dll";
[DllImport(_fileDll, EntryPoint = "_RSAEncryptString@16", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern void RSAEncryptString(char[] sInput, char[] mn, char[] me, StringBuilder cipher);
/// <summary>
/// 加密
/// </summary>
/// <param name="data"></param>
/// <param name="keye"></param>
/// <param name="keyn"></param>
/// <returns></returns>
public static string Encrypt(string data, string keye, string keyn)
{
Encoding encode = Encoding.Default;
byte[] bData = encode.GetBytes(data);
byte[] bKeye = encode.GetBytes(keye);
byte[] bKeyn = encode.GetBytes(keyn);

        StringBuilder sInputTmp = new StringBuilder(5000);

        RSAEncryptString(encode.GetChars(bData), encode.GetChars(bKeyn), encode.GetChars(bKeye), sInputTmp);

        return sInputTmp.ToString();
    }
支持(0) 反对(0) 水知寒 | 园豆:2 (初学一级) | 2018-09-03 13:59

@水知寒: 非常感谢!测试可以!另外,不知道你那边3des加密解密的算法是怎么处理的?也是调用海信的加密算法?

支持(0) 反对(0) ccczzz | 园豆:202 (菜鸟二级) | 2018-09-08 12:44

@ccczzz: 对哈,他里面有一个,就直接调用的

支持(0) 反对(0) 水知寒 | 园豆:2 (初学一级) | 2018-09-11 14:48

@水知寒: 你好,请问下3des这边能否也给下实例代码是如何加密解密的?

支持(0) 反对(0) ccczzz | 园豆:202 (菜鸟二级) | 2019-01-06 03:04

因为我用c#实现的3DES算法一直都无法成功调用接口,所以如果海信有这个算法的话,麻烦告诉一下是怎么调用的

支持(0) 反对(0) ccczzz | 园豆:202 (菜鸟二级) | 2019-01-08 15:06
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册