我正在生成RSA私人&公钥使用OpenSSL,将公钥发送到HTML页面加密用户名&密码(使用JSEncrypt)。加密内容发送到服务器使用私钥解密。这是我的解密功能:
public string RsaDecrypt(string xmlPrivateKey, string mStrDecryptString)
{
string str2;
try
{
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
provider.FromXmlString(xmlPrivateKey);
byte[] rgb = Convert.FromBase64String(mStrDecryptString);
byte[] buffer2 = provider.Decrypt(rgb, false);
str2 = new UnicodeEncoding().GetString(buffer2);
}
catch (Exception exception)
{
throw exception;
}
return str2;
}
xmlPrivateKey值为:
MIICWwIBAAKBgQCt8y+vx9Y3Iik9l/8r6x+wjcrgPskbjVpt7fSJqtpCA/XaYl/3O2uvrRUPzyqr1wA+ejsdhdm285nYSbSaHTPem1+N/JHynp+cLQiBV6a8PayOvtrSBaHLZDDhgvntk/BLeplU406kiMltnVDko33H+Y3yaNuY2TNDEMe5Z8OlUQIDAQABAoGAdYIChMyKeVQqZ+F2D0UWcz5V/oZrdKFYpUpKF3XDWzUxsAUkru8FH/fccoGQYeUr1QjdRmRVXrHRC7s+tZ1km68oiUFD6sbCYyPQy0Se95050FncM3lEndGUJTiTelVqAYh+DPVnRURcfgA+HSvWek1/YnOZ8UNZJ36jiogSKcECQQDbRfn/UODXud7MKO7zfYOLvPhtFMgtA0Ac5w6tTJ/llZs0QtjMKCNHF9bGRxKdFvKTMA1DGBNN0chdWAc7UET/AkEAyxXUJAk1+46fRhzTH4uXRX7SEMCwEjY79DHqE23pPx8Q8VC3j2aPETQerT4EHNzaMBg6hneJE2p7xB5Rm/SFrwJAIWasaT7psRLIJHNLyt1gr2WOthcHUwv+tShhLPbSGIfMh45zNc4baZXxCm0DIdjABLm6G3FMZ3tAOS/Ski9tAwJAMYWQJn1sgXwk0KcEwIN8jsC/HsCt7rL06bYmOzipEPBVZFLnf/tlVa+c72fY/uTH+8RcuR96+JYVuhwekGYPFwJAQXbsOkyVTvZGcqRk9+SF7AUsGcHYPrImH6iafYEBsVCOrMJfjEai0zmd/9A1j+NHFq31KPAQGV0zHmV2NXscDg==
mStrDecryptString是:
fW9H+/Nz/yp6my/EwY0I+KP1CX/QPY8TL3bFDvfJYJDJ50LHEPfiR/RGhHl9rvViXOgD4IiXYF2/KbNPQNmno+Bioi3r8Xc5+PVNyFDJy+X4/YjX4O830g9vAhyRJ1RKbJOmJYWT4sdP0jfxwaRL2+FAl6yIsrcsH/7bRZvjDTU=
在服务器端解密时,错误是:第1行中的语法无效。
我该怎么做才能做到对不对?
答案 0 :(得分:4)
OpenSSL生成的RSA格式与.NET不同,您应该将OpenSSL RSA xmlPrivateKey
转换为 XML格式,以便RSACryptoServiceProvider
识别它。
private static RSACryptoServiceProvider DecodeRsaPrivateKey(string priKey)
{
var privkey = Convert.FromBase64String(priKey);
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
// --------- Set up stream to decode the asn.1 encoded RSA private key ------
var mem = new MemoryStream(privkey);
var binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
try
{
var twobytes = binr.ReadUInt16();
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8230)
binr.ReadInt16(); //advance 2 bytes
else
return null;
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102) //version number
return null;
var bt = binr.ReadByte();
if (bt != 0x00)
return null;
//------ all private key components are Integer sequences ----
var elems = GetIntegerSize(binr);
MODULUS = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
E = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
D = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
P = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
Q = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DP = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DQ = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
IQ = binr.ReadBytes(elems);
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
var rsa = new RSACryptoServiceProvider();
var rsAparams = new RSAParameters
{
Modulus = MODULUS,
Exponent = E,
D = D,
P = P,
Q = Q,
DP = DP,
DQ = DQ,
InverseQ = IQ
};
rsa.ImportParameters(rsAparams);
return rsa;
}
catch (Exception e)
{
LogHelper.Logger.Error("DecodeRsaPrivateKey failed", e);
return null;
}
finally
{
binr.Close();
}
}
private static int GetIntegerSize(BinaryReader binary)
{
byte binaryReadByte = 0;
var count = 0;
binaryReadByte = binary.ReadByte();
if (binaryReadByte != 0x02) //expect integer
return 0;
binaryReadByte = binary.ReadByte();
if (binaryReadByte == 0x81)
{
count = binary.ReadByte(); // data size in next byte
}
else
{
if (binaryReadByte == 0x82)
{
var highbyte = binary.ReadByte();
var lowbyte = binary.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = binaryReadByte; // we already have the data size
}
}
while (binary.ReadByte() == 0x00)
{ //remove high order zeros in data
count -= 1;
}
binary.BaseStream.Seek(-1, SeekOrigin.Current); //last ReadByte wasn't a removed zero, so back up a byte
return count;
}
因此RSACryptoServiceProvider
可以解密原始上下文。