我有openssl命令可以正常工作:
5 4 [6 7 3] 1 2
-> 5 4 3 [7 6 1 2]
-> [5 4 3 2 1] 6 7
-> 1 2 3 4 5 6 7
并输出所需的结果:
echo -n "my_password" | openssl pkeyutl -sign -inkey /home/ramunas/Downloads/id_rsa | base64 -w 0
RSA密钥(PKCS8):
Q9dyYKFvGOELAZYN8O18l30/bC/hVBm+7sy0DFJkspSvQa4bY7xGGsRina99ivxbdsu4BaakXDdA/X9wxP/Ll/GpEUS9xteiVNQkOEYOl27OAhe0OsC6zRDKpRPJEFhfLVt0cHlDILRZ0yuJLfv0UiwF0CTe4Xv5AN3RXrv28nIS8XA0o/TmCB5XlG12Zq7UdFoDF+j6oFXMyWAV9eXa1uQdNzIAm8wPn4e3lEz4v8p/M5PhLlAO2rBTEw79PiqFtKqlJ1OAZan8As02ejBjpe3t55dKuQke5+S1/7Zt7bZozDeswSMYbb643ZbLW+QN0AoO7pMy4w8qugzQZ/gnfw==
但我需要使用C#签名密码,在this answer的帮助下我创建了RSA提供程序。这与示例中的大致相同,但需要在一个地方添加字节搜索,我怀疑密钥与链接中的密钥相比有更多信息。顺便说一下,我用openssl输出模数部分和c#,它们匹配除了第一个十六进制数
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCfHlwo+7jE6TKGGquuLDcrj+gPiWpl7QKpUAa8rqCs+A0iGbIM843U+uRx5mAhoBSJhBL9XPZss+IEKGy29K6bdy8sCXBvU+rjjPC/q91Sg5pw84063h8sOvV0UIFZVFZBt4Ax53qhOWFMAGtNB55LPvih71uz+iI5KneeS6OgAeBy1I+fJG1SiFDyOZsugma4f50ACXtI4hVtYSmM3/hY3XpWGQdUJPKByTfIxHg1v6EdMZ7mlOjYSFZxCVQRSXUAVf9ctPQQ4iA4gn69uveYH/fZQTc+7M3FGGsYVY2q31N+3jRbppOi6NqqISPckfXKnlTNkTkjXM0ZbZSvJrk3AgMBAAECggEAZjItpvTlmzLbjF4c3eTwGj53IWN0vroW93+6k/zknbNDXB98x+y1r5DkoHMCUxZpmlkFiUznyLFP/LOp/2fvrVJDLdlyKU6Qkk23YqOTpqd3zgvfLWv0QYgsleQO77zHGbYt09+EV4BvCU1LnVHDTTjIn9kH4PRKfsTTxwt1sBH//kXwZaRlvKxP0C9EGXPCymgdFO9RAhaVURDx3x7prKGRJbPDSMIP09elhChQ2fHvTDlqvrnr71hIR1ge8uGMkRta0gv3VyXpbAOrVJqxzmiccUIQoocWVLNCPXFZTe/7BFx1esLH4nGUwC57yiw9KudVhl5oeMIcHjKyrnoeIQKBgQDeuGqEqvGzlX/ZTt9S9LBj04OMA+0T2Lg/rg8pbn3MsqCLPikaf55Xpx5Le8fgc9cQzZYaLb22bEMAkl38EEttTK0ChWFnViGVYrxTDuQZA2eKljLrmuiynrjOdJq1Sro7bRsSOPYO32BwdGZ2/KJCJkocgRP2Mi9nALlrBfcRswKBgQC25QZIeynG2DHSR6rUTNhurVqbVHE5CWfmABdUHyg90y0DSjeKLad3z42Zln5mKfcapjWqL4443HAJ8ggdkyyYuif0RO4L2NBBKL/GxSjpeRgEZfmhOMgJLEy9dAzWSaiH1B5/MY1ZWxXWJBinOgu7ME6rrK5pEZDq/ySApkMQbQKBgBPx9fANkvmfIMToME2whf9amMQ4Mcn+NXnWb5spPvDO6lut5GZwGVEGMUtXOW4bUZ46mv+bKwskJNfvQ6VoHCkcnb3FDhT//J/xKKZThg/LY0Fg9AxvYfllB23NuXEU0RqzSaJXIYnxbSSE+Awd0bYU0bw9vvjkQ6R4xyITda3LAoGBALEcB4GZA1OzeEuRazQ7VjuXU+6nTx1UpnBsFis4INf979EHxdDhdRLows7AlZaJfOkpmz463xbhIP4AiytYog8j9hztwzdltgXjWBM8SeoNgdyAg8REIDIB3C56exPoMHOYThAOBDtLoVHFkrod085pcUV960eD4zot6UNLvhXhAoGBAITXSidOCGfkUVj8/oItR/IV+gwqFZFMoXDD8vJ/0G99Rjib4rWcX6B3NxamnNA6EfiGaMTdWZaxFbJOPh2K7OcOlDCWNpMvEQQyI0nhGKkKCujiTfBkSWkKDHdEAC/p0k2rAh4feYabdvX+ePmWAs6/X/syQ69jBk2Y6PhUsJH3
通过此提供商,我尝试"签署"我的数据,但结果与openssl
不匹配private RSACryptoServiceProvider CreateRsaProviderFromPrivateKey(string privateKey)
{
var privateKeyBits = System.Convert.FromBase64String(privateKey);
var RSA = new RSACryptoServiceProvider();
var RSAparams = new RSAParameters();
using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits)))
{
byte bt = 0;
ushort twobytes = 0;
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130)
binr.ReadByte();
else if (twobytes == 0x8230)
binr.ReadInt16();
else
throw new Exception("Unexpected value read binr.ReadUInt16()");
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102)
throw new Exception("Unexpected version");
bt = binr.ReadByte();
if (bt != 0x00)
throw new Exception("Unexpected value read binr.ReadByte()");
for (int ii = 0; ii < 26; ii++) //!!! this one needs explanation
binr.Read();
RSAparams.Modulus = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.Exponent = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.D = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.P = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.Q = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.DP = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.DQ = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.InverseQ = binr.ReadBytes(GetIntegerSize(binr));
}
RSA.ImportParameters(RSAparams);
return RSA;
}
private int GetIntegerSize(BinaryReader binr)
{
byte bt = 0;
byte lowbyte = 0x00;
byte highbyte = 0x00;
int count = 0;
bt = binr.ReadByte();
if (bt != 0x02)
return 0;
bt = binr.ReadByte();
if (bt == 0x81)
count = binr.ReadByte();
else
if (bt == 0x82)
{
highbyte = binr.ReadByte();
lowbyte = binr.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = bt;
}
while (binr.ReadByte() == 0x00)
{
count -= 1;
}
binr.BaseStream.Seek(-1, SeekOrigin.Current);
return count;
}
答案 0 :(得分:1)
问题是openssl pkeyutl -sign
没有按照您的想法行事。 (你想要openssl dgst -sign
)
$ echo -n "my_password" | \
> openssl pkeyutl -sign -inkey rsa.key | \
> openssl rsautl -inkey rsa.key -verify -raw -hexdump
0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0020 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0030 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0040 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0050 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0060 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0070 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0080 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0090 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
00a0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
00b0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
00c0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
00d0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
00e0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
00f0 - ff ff ff ff 00 6d 79 5f-70 61 73 73 77 6f 72 64 .....my_password
请注意,它在填充块的末尾包含my_password
,而不是该值的摘要。
openssl pkeyutl -sign
将输入作为后摘要格式化的输入数据,在PKCS#1签名的情况下,它应该是DER-Encoded DigestInfo,描述使用哪种摘要算法以及得到的摘要是什么({ {3}}第2步)。这几乎意味着你永远不想使用该命令。
将此与openssl dgst -sign
:
$ echo -n "my_password" | \
> openssl dgst -sha256 -sign rsa.key | \
> openssl rsautl -verify -raw -hexdump -inkey rsa.key
0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0020 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0030 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0040 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0050 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0060 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0070 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0080 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
0090 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
00a0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
00b0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
00c0 - ff ff ff ff ff ff ff ff-ff ff ff ff 00 30 31 30 .............010
00d0 - 0d 06 09 60 86 48 01 65-03 04 02 01 05 00 04 20 ...`.H.e.......
00e0 - f6 e2 48 ea 99 4f 3e 34-2f 61 14 1b 8b 8e 3e de ..H..O>4/a....>.
00f0 - 86 d4 de 53 25 7a bc 8d-06 ae 07 a1 da 73 fb 39 ...S%z.......s.9
如果我们将openssl dgst -sign
的输出发送到base64
:
GP0L9sIrk0QV6r+ZfP42yq9pWGDF5OwdoStvolp+DKzSxpc+eSItpIJrt6VIkfOMeyJG3GZUSDf2
Z5iLTzZ+NAQBj0ay0Y0FH81rg2oTAtJ/vbh5+jB3Akgkct8xosJpjJDNaDIUb6gN+QcCS0g1Nbsn
YFetFoH7lX2oDmkaAWdiBquLmCdiA8lsRGs9YocuhDghj36TCjvrqS0ZheX0Oa1rM9xFMFATdFTg
BJffGWVoZzikZ6orVG0BZ2XOh6DvxBnjqZZQ40ru20bfq40qT1iZmf72bQ7/rayOcVNxDi09UV6+
kXYSz++mJvzpOe+MIwaFlrZVUlcgDXvKhZtbRQ==
在.NET中使用带有该密钥的SHA256签名时,应该使用相同的值。
答案 1 :(得分:1)
只需在Windows中使用OpenSSL解决问题(在tutorial的帮助下下载并构建二进制文件)。唯一的区别是你必须传递密码文件而不能从命令行读取输出(命令行输出不是马赫文件输出并且是incorect)。我的代码如下:
Settings/Preferences