都已经记不得弄了多少天了,哪位大神帮帮忙啊!/(ㄒ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;//返回密文
方法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;
方法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;
虽然我点不开你的代码,但是我觉得方法3就行了,至于你的“分段加密”因为看不到代码,不知道什么意思,RSACryptoServiceProvider 支持大于 KEY 长度的数据加密,不用你分段。
谢谢 @Launcher ,对方编译了一个dll把加密算法打包进去了,我直接调用他的解决了。
等项目结束了一定要研究透彻,倒是希望给予帮助,谢谢了。
你好,我也遇到这个问题,请问你是用C#调用海信的dll吗
我们最后是直接把海信给的RSADLL.dll直接放到bin目录下面,就可以调用了
@水知寒: 请问调用有示例代码参考吗?我最近在对接海信的会员接口
@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();
}
@水知寒: 非常感谢!测试可以!另外,不知道你那边3des加密解密的算法是怎么处理的?也是调用海信的加密算法?
@ccczzz: 对哈,他里面有一个,就直接调用的
@水知寒: 你好,请问下3des这边能否也给下实例代码是如何加密解密的?
因为我用c#实现的3DES算法一直都无法成功调用接口,所以如果海信有这个算法的话,麻烦告诉一下是怎么调用的