我需要能够使用C#解密服务器上的字符串,但是该字符串是使用公钥加密和客户机上的cryptico.js加密的。有关详细信息,请参阅结尾处的上下文。
Cryptico给了我一个这样的私密RSA密钥(注意--“喜欢”这个--我为这个问题创建了一个新的密钥):
Array ( [n] => 8029845567507477803775928519657066509146751167600087041355508603090505634905205233922950527978886894355290423984597739819216469551137046641801207199138209 [e] => 3 [d] => 5353230378338318535850619013104711006097834111733391360903672402060337089936682996269976597251251223844095913209399106464214877696419418951728015128013411 [p] => 102067954277225510613941189336789903269738979633396754230261162567549753196947 [q] => 78671563708406591396117399809764267229341143260756252277657051641634753921147 [dmp1] => 68045302851483673742627459557859935513159319755597836153507441711699835464631 [dmq1] => 52447709138937727597411599873176178152894095507170834851771367761089835947431 [coeff] => 26458340158787140383846156526777567128582042036682248240414722856369310516021 ...plus一堆方法。
我正试图解密它:
RSAParameters parameters = new RSAParameters();
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
parameters.Exponent = encoding.GetBytes("3");
//dmp1
parameters.DP =
encoding.GetBytes("68045302851483673742627459557859935513159319755597836153507441711699835464631");
//dmq1
parameters.DQ =
encoding.GetBytes("52447709138937727597411599873176178152894095507170834851771367761089835947431");
//d
parameters.D =
encoding.GetBytes(
"5353230378338318535850619013104711006097834111733391360903672402060337089936682996269976597251251223844095913209399106464214877696419418951728015128013411");
//p
parameters.P =
encoding.GetBytes("102067954277225510613941189336789903269738979633396754230261162567549753196947");
//q
parameters.Q =
encoding.GetBytes("78671563708406591396117399809764267229341143260756252277657051641634753921147");
//n
parameters.InverseQ =
encoding.GetBytes(
"8029845567507477803775928519657066509146751167600087041355508603090505634905205233922950527978886894355290423984597739819216469551137046641801207199138209");
//coeff
parameters.Modulus =
encoding.GetBytes("26458340158787140383846156526777567128582042036682248240414722856369310516021");
RSA rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(parameters);
var decryptThis = encoding.GetBytes(ciphertext);
var result = rsa.DecryptValue(decryptThis);
resultString = encoding.GetString(result);但这就排除了“坏数据”的例外。
有谁更有经验的C#有任何想法,我的错吗?
谢谢,
G
上下文的详细信息:我试图在应用程序的客户端和服务器端实现密码强度检查功能,但只使用服务器端的代码。为了在客户端实现这一目标,我希望将假定的密码发送到服务器,判断其强度,然后返回显示在客户端的分数。这意味着我只需要在服务器上维护密码强度检查代码。作为额外的安全措施,在将密码发送到服务器进行判断之前,我将使用cryptico.js库加密假定的密码。
发布于 2013-04-04 11:05:47
BigInteger和RSAParameter类以不同的格式存储数字。
BigInteger将数字存储为小-endian--这意味着如果您创建一个BigInteger来保存十六进制数0xABCD (43981) - ToByteArray将返回字节{0xCD、0xAB、0x00} (稍后将进一步讨论)。
RSAParameter被设计成以大端格式存储数字.这意味着写入例如指数属性的字节{0xCD、0xAB、0x00}将被RSA实现解释为数字0xCDAB00 (13478656)。
为了使事情变得更复杂,RSAParameters总是正数,而BigInteger支持符号。同样的数字,0xFF -将被不同的解释。对于RSA,它是小数点255。对于BigInteger来说,它的意思是-1,因为它将最重要的位解释为一个符号。这就是为什么添加零的原因--在构建时,BigInteger知道我们正在传递正值,43981。但是将此值存储为两个字节将产生负数(-21555),因为字节0xCD (二进制11001101)设置了最高位。所以BigInteger加零表示正数。你自己试试看:
Console.WriteLine(new BigInteger(new byte[]{0xCD,0xAB}));
Console.WriteLine(BitConverter.ToString(new BigInteger(0xABCD).ToByteArray()));因此,我们将大整数作为十进制字符串“1234567.”传递给我们,我们希望将其转换为RSA所使用的表示形式。为了做到这一点,我们需要:
代码(使用参数):
using System;
using System.Numerics;
using System.Security.Cryptography;
using System.Text;
class App
{
static void Main()
{
var parameters = new RSAParameters();
parameters.Exponent=B("3");
parameters.Modulus=B("8029845567507477803775928519657066509146751167600087041355508603090505634905205233922950527978886894355290423984597739819216469551137046641801207199138209");
parameters.D=B("5353230378338318535850619013104711006097834111733391360903672402060337089936682996269976597251251223844095913209399106464214877696419418951728015128013411");
parameters.P=B("102067954277225510613941189336789903269738979633396754230261162567549753196947");
parameters.Q=B("78671563708406591396117399809764267229341143260756252277657051641634753921147");
parameters.DP=B("68045302851483673742627459557859935513159319755597836153507441711699835464631");
parameters.DQ=B("52447709138937727597411599873176178152894095507170834851771367761089835947431");
parameters.InverseQ=B("26458340158787140383846156526777567128582042036682248240414722856369310516021");
var rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(parameters);
var ciphertext = rsa.Encrypt(Encoding.ASCII.GetBytes("Hello"), false);
Console.WriteLine(Encoding.ASCII.GetString(rsa.Decrypt(ciphertext, false)));
}
static byte[] B(string s)
{
var b = BigInteger.Parse(s);
var ret = b.ToByteArray();
if (ret[ret.Length - 1] == 0)
{
Array.Resize(ref ret, ret.Length - 1);
}
Array.Reverse(ret);
return ret;
}
}https://stackoverflow.com/questions/13644525
复制相似问题