我已经使用Node rsa在Node中生成了一对私钥和公钥,并且可以在Node中使用这些密钥成功地进行签名和验证。
我尝试使用公钥的模和指数来验证中的签名(由节点中的私钥签名)。网
e、 g.我有一个string=“foo”,它有一个由Node生成的签名“abc123”。在里面NET我想使用公钥的模和指数来确认签名“abc123”对“foo”有效。
我想使用模数和指数而不是直接使用公钥的原因是因为我想创建一个Web服务,该服务在一个众所周知的地址公开一个jwks.json文件,任何人都可以验证该服务生成的令牌。
这是我在节点中工作的代码:
let privateKey = fs.readFileSync('privateKeyPKCS1.pem');
let publicKey = fs.readFileSync('publicKeyPKCS1.pem');
let testpublicForExport = new NodeRSA(publicKey);
let keyComponents = testpublicForExport.exportKey('components-public');
console.log(keyComponents.n.toString('base64'));
let sign = crypto.createSign('RSA-SHA256');
let stringToSign = 'hello';
sign.update(stringToSign);
let sig = sign.sign(privateKey, 'base64');
console.log('sig='+sig);
let verify = crypto.createVerify('RSA-SHA256');
verify.update(stringToSign);
console.log(verify.verify(publicKey, sig, 'base64'));
这是我要的。NET(我猜这部分有点错误):
string modulus = "AJ/dk3x2xQjvNTJpRh/yW6vURVhkubHVrXk33zd76k7/VnHS/8RE49IM+d137kvz8SgVQBOcN1P2yhOFuhbtYR7spwQ5lhob9GNkzR4l/ybgcriIIwGO0vmo264Xz2vERhZ7cVITOvn49VpWRbeVS3Gsn3ecSILdeoh2yNoevqwFGnuPeVyD4JOwo+JhEhXDlzth9UFu18x5k7NNLG2gywI7qX/qMd1+2rnDI33rSLpXiPXGQg9BCmatMx+R4sWV2AGOx9YxI/YBUTl0hSGcWtzsPxGA2zY3oBT0P9FGg+QYvVjHdAkuJsx9QpPo0TlNbrNvodj3KEUwxoGwnWu6Ick=";
int exponent = 65537;
string stringToSign = "hello";
string sig = "fGpD/SMPvS2CK9D4Z4ykUj+dRmPOIK92wdaRnhpAl3toOLdNT+96PUoCQKJ30UIRyXchIlmCvg+QH/MwimXueyY/oBwMH36EpajyraJZA/2RRA3/F7hRIT6/G9lJe69npeGyvMx+LlIov9B+I99KSLiVdYYPSrU4eUb3fe4wuZZd/cSIcwnIVvCrjOSUZAF09sfKx7Qt6LhTcQm2J332PsvotEZUuwTRsHh0QMMUd/eIWZ+yPfPGMX4D5WJEUxnlQT2f9Vfxx7JBnx5IDI9Jf6ohJCl5bymeKjh4ZsBqRINGG0aiElZdhGdcsGfhZGjRR2MMQkIo7ZSRrtaaKO5u9g==";
RSA rsa = RSA.Create();
rsa.ImportParameters(new RSAParameters()
{
Modulus = Convert.FromBase64String(modulus),
Exponent = BitConverter.GetBytes(exponent)
});
bool isVerified = rsa.VerifyData(Encoding.UTF8.GetBytes(stringToSign), Convert.FromBase64String(sig), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
如果有必要,我很乐意使用bouncy castle(尽管我对它不是很熟悉)。
我试图仅使用公钥的模和指数来验证RSA签名。
谢谢。
我不知道为什么。NET RSA类无法验证签名,一切正常。以下是BouncyCastle代码:
string modulus = "AJ/dk3x2xQjvNTJpRh/yW6vURVhkubHVrXk33zd76k7/VnHS/8RE49IM+d137kvz8SgVQBOcN1P2yhOFuhbtYR7spwQ5lhob9GNkzR4l/ybgcriIIwGO0vmo264Xz2vERhZ7cVITOvn49VpWRbeVS3Gsn3ecSILdeoh2yNoevqwFGnuPeVyD4JOwo+JhEhXDlzth9UFu18x5k7NNLG2gywI7qX/qMd1+2rnDI33rSLpXiPXGQg9BCmatMx+R4sWV2AGOx9YxI/YBUTl0hSGcWtzsPxGA2zY3oBT0P9FGg+QYvVjHdAkuJsx9QpPo0TlNbrNvodj3KEUwxoGwnWu6Ick=";
int exponent = 65537;
string stringToSign = "hello";
string sig = "fGpD/SMPvS2CK9D4Z4ykUj+dRmPOIK92wdaRnhpAl3toOLdNT+96PUoCQKJ30UIRyXchIlmCvg+QH/MwimXueyY/oBwMH36EpajyraJZA/2RRA3/F7hRIT6/G9lJe69npeGyvMx+LlIov9B+I99KSLiVdYYPSrU4eUb3fe4wuZZd/cSIcwnIVvCrjOSUZAF09sfKx7Qt6LhTcQm2J332PsvotEZUuwTRsHh0QMMUd/eIWZ+yPfPGMX4D5WJEUxnlQT2f9Vfxx7JBnx5IDI9Jf6ohJCl5bymeKjh4ZsBqRINGG0aiElZdhGdcsGfhZGjRR2MMQkIo7ZSRrtaaKO5u9g==";
var signer = Org.BouncyCastle.Security.SignerUtilities.GetSigner("SHA256withRSA");
signer.Init(false, new Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters(
false,
new Org.BouncyCastle.Math.BigInteger(1, Convert.FromBase64String(modulus)),
Org.BouncyCastle.Math.BigInteger.ValueOf(exponent)));
byte[] data = Encoding.ASCII.GetBytes(stringToSign);
signer.BlockUpdate(data, 0, data.Length);
bool ok = signer.VerifySignature(Convert.FromBase64String(sig));
这里有两个问题。
首先,假设使用的键为65537,则指数的值不正确。
您调用了位转换器。GetBytes
,它生成{0x01,0x00,0x01,0x00}
(小尾端),在上下文(大尾端)中用作16777472
,比预期的大256倍。
最好的办法是将其保存到值为{0x01,0x00,0x01}
的静态数组中。
其次,Javascript代码在其DER编码表示中输出模值,这意味着它以0x00开始。RSAParameters类期望整数值是无符号的,因此它表示您导入了一个稍微无效的2056位密钥。然后,它断然拒绝签名,因为签名的大小不适合密钥。您需要删除前导0x00。
总而言之:
string modulus = "AJ/dk3x2xQjvNTJpRh/yW6vURVhkubHVrXk33zd76k7/VnHS/8RE49IM+d137kvz8SgVQBOcN1P2yhOFuhbtYR7spwQ5lhob9GNkzR4l/ybgcriIIwGO0vmo264Xz2vERhZ7cVITOvn49VpWRbeVS3Gsn3ecSILdeoh2yNoevqwFGnuPeVyD4JOwo+JhEhXDlzth9UFu18x5k7NNLG2gywI7qX/qMd1+2rnDI33rSLpXiPXGQg9BCmatMx+R4sWV2AGOx9YxI/YBUTl0hSGcWtzsPxGA2zY3oBT0P9FGg+QYvVjHdAkuJsx9QpPo0TlNbrNvodj3KEUwxoGwnWu6Ick=";
int exponent = 65537;
string stringToSign = "hello";
string sig = "fGpD/SMPvS2CK9D4Z4ykUj+dRmPOIK92wdaRnhpAl3toOLdNT+96PUoCQKJ30UIRyXchIlmCvg+QH/MwimXueyY/oBwMH36EpajyraJZA/2RRA3/F7hRIT6/G9lJe69npeGyvMx+LlIov9B+I99KSLiVdYYPSrU4eUb3fe4wuZZd/cSIcwnIVvCrjOSUZAF09sfKx7Qt6LhTcQm2J332PsvotEZUuwTRsHh0QMMUd/eIWZ+yPfPGMX4D5WJEUxnlQT2f9Vfxx7JBnx5IDI9Jf6ohJCl5bymeKjh4ZsBqRINGG0aiElZdhGdcsGfhZGjRR2MMQkIo7ZSRrtaaKO5u9g==";
byte[] modulusBytes = Convert.FromBase64String(modulus);
if (modulusBytes[0] == 0)
{
modulusBytes = modulusBytes.Skip(1).ToArray();
}
RSA rsa = RSA.Create();
rsa.ImportParameters(new RSAParameters()
{
Modulus = modulusBytes,
Exponent = new byte[] { 0x01, 0x00, 0x01 },
});
bool isVerified = rsa.VerifyData(Encoding.UTF8.GetBytes(stringToSign), Convert.FromBase64String(sig), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
Console.WriteLine(isVerified);
我正在尝试将支付网关集成到我的nodejs应用程序中。当支付完成时,网关用支付结果将用户重定向到我的站点。结果是RSA签名的,我需要用支付网关提供的公钥来验证它。 下面是支付网关为签名验证提供的示例PHP代码。 有谁知道怎么把这件事搞定吗?
我在理解RSA签名和验证的概念方面有一个小问题。问题是我可以创建密钥对(公钥和私钥),这是完全好的。 签名和验证如下: 当我打印myPrivateKey和myPublicKey时,我看到公钥和私钥的模(n)和公钥指数(e)是相同的。 我已经将公钥和私钥转换为base64和hex,我得到了不同的值,这是非常好的。但是,我不能用base64或十六进制对消息进行签名。我只能用我从这里得到的东西来签名:
问题内容: 我有一个字符串,一个签名和一个公共密钥,我想验证字符串上的签名。密钥如下所示: 我已经阅读了一段时间的pycrypto文档,但是我不知道如何使用这种密钥制作RSAobj。如果您了解PHP,我将尝试执行以下操作: 另外,如果我对任何术语感到困惑,请告诉我。 问题答案: 标记之间的数据是包含PKCS#1 RSAPublicKey的PKCS#8 PublicKeyInfo的ASN.1 DER
问题内容: 我试图使自己熟悉pycrypto模块,但是缺少清晰的文档使事情变得困难。 首先,我想了解签名和验证数据。有人可以举例说明如何写吗? 问题答案: 这是文档中示例的丰富版本:
我正在处理C RPC客户端。我需要使用OpenSSL对mime数据进行签名,并将公钥和签名发送到服务器。Java将尝试使用公钥验证签名。 问题是,JAVA无法验证OpenSSL生成的签名,但可以验证JAVA生成的签名。你知道如何修复我的c客户端代码吗? C客户端代码: JAVA代码:
我有一个JavaScript客户端和一个Node服务器。JS.我试图在客户端签署一个简单的文本,并将签名与公钥一起发送到服务器,然后服务器可以验证公钥。 客户端的任何东西都可以!但我无法在服务器端验证签名。我认为您没有必要阅读客户机代码,但为了保证,我也会提供它。 客户代码: 服务器代码(为此我使用express): 服务器控制台日志: 注: 我认为在服务器中正确导入了公钥,因为当我在服务器中再次