首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >RSA SHA256签名生成和验证

RSA SHA256签名生成和验证
EN

Stack Overflow用户
提问于 2017-02-06 05:23:21
回答 1查看 7.3K关注 0票数 1

我使用BouncyCastle在C#中生成一个RSA签名,并在Go中验证签名。

但是由于某些原因,来自C#程序的签名不会在Go中生效。

详细信息:

公钥/私钥对是从Online RSA Key Generator生成的示例

散列字节数组是使用SHA265生成的数组,为简单起见,它是硬编码的。

我已经为BouncyCastle尝试了不同的签名算法,尝试了密钥对,但似乎都不起作用。

我还验证了签名的字节数组在两种语言之间是否匹配...

谁能告诉我我这里漏掉了什么?或者至少如何进一步调查?

生成签名的C#代码

代码语言:javascript
运行
复制
    static void Main(string[] args)
    {
        byte[] hashBytes = new byte[32] { 152, 154, 255, 19, 168, 20, 167, 43, 232, 133, 146, 13, 183, 80, 186, 85, 180, 249, 95, 142, 234, 71, 93, 188, 29, 147, 220, 164, 248, 83, 196, 80 };
        String privateKeyPemStr = @"-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCIw68jARnmvTh+xvMcv5iugtoHXt60NWEebfbghLTFuTlQvK0e
xY5hxnN/uD2UVc/S3QGnBQn0AfynhxlEZkedpYBb5RWoVChGZMHu7hbZukMjByjx
ec0LjtuEQhY4m18XaVNmAQWD/EiROMGTghMwykkQ+SBtx4Gl/O/BB6F4SQIDAQAB
AoGAJLarODFee6OGG/paXvhMC2TTFLFyBVxjAuEwKdtWD9IGQdc0fhM4gqTccofJ
+B0FGiz7+ZMPtfImme5ZaRQv2wx7KOPbOdAyYxC7nLFCHYqDWZJ8/cCoS+hPJFd5
9OeGLGz3QKfEEPtYEAw4+E/UjilYAtRNREkISkYoB9Va8PUCQQDDHMPRSCfXbfZV
ufmlRZj2bH8sjVaSBbJIw+y9HKJ3ORRnKGjtIZ/+z70EwMwtbbQKnl71SruO5HB9
AUTtRka/AkEAs3GWQhplPbuH/fAlaEPy5GQilUNRt76NMsgtIFWPMXnt82cxTUUR
RIKwX7M96WBppPZ2Dy7uLrX8O+3fr6BK9wJATZ0lsBy57JKLiTJ/wmTbIjuqozhe
FZw6fYOiqt+3KSIFobuLcbkMgjp1AG0JS5D2K7swHvdpgMASl0dn+dMY1QJBAIPw
9QbN2bs2dJvnQ9oSfDoq1rLhuOheF/xK68Nmpc8/VBMwwTOLoVK6tWzoopFC7ur4
vX4Uh9WYwkpecab1OakCQD0SCs4zIggA/2NkUx8J5H07/drbm9uH+98EQUvzjTdz
qSW2jJPCA4GYYmtnnDRduukjmkJlbaaTdEH5YLCilF0=
-----END RSA PRIVATE KEY-----";

        StringReader strReader = new StringReader(privateKeyPemStr);
        PemReader pemReader = new PemReader(strReader);
        AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
        RsaKeyParameters privateKey = (RsaKeyParameters)keyPair.Private;


        ISigner sig = SignerUtilities.GetSigner("SHA256withRSA");
        sig.Init(true, privateKey);
        sig.BlockUpdate(hashBytes, 0, hashBytes.Length);
        byte[] signedBytes = sig.GenerateSignature();

        var signedStr = Convert.ToBase64String(signedBytes);

        Console.WriteLine(signedStr);
        Console.ReadLine();            
    }

这是我验证签名的Go代码。我将C#代码的结果复制到签名变量中

代码语言:javascript
运行
复制
func main() {
pubKeyStr := `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCIw68jARnmvTh+xvMcv5iugtoH
Xt60NWEebfbghLTFuTlQvK0exY5hxnN/uD2UVc/S3QGnBQn0AfynhxlEZkedpYBb
5RWoVChGZMHu7hbZukMjByjxec0LjtuEQhY4m18XaVNmAQWD/EiROMGTghMwykkQ
+SBtx4Gl/O/BB6F4SQIDAQAB
-----END PUBLIC KEY-----`
pemBlockPub, _ := pem.Decode([]byte(pubKeyStr))
pub, _ := x509.ParsePKIXPublicKey(pemBlockPub.Bytes)
publicKey, _ := pub.(*rsa.PublicKey)

signatureStr := "YJxDTSMnFb4uh/orsUjHTHEsW1dkxuStsGP0PmjmObJhog/7OQfWgBcBZ58w0qWoknLGMVBBgZTgJtKq1ZSSTsx9uXhNKEhNEI3a+7ZhmPiHp6JRLbftsEoGKe7FKU8vXkp6Bo90qMOoJz54YI2xue8EA9b5PTgjkGbDbKdimF8="
signatureBytes, err := base64.StdEncoding.DecodeString(signatureStr)
hashBytes := [32]byte{152, 154, 255, 19, 168, 20, 167, 43, 232, 133, 146, 13, 183, 80, 186, 85, 180, 249, 95, 142, 234, 71, 93, 188, 29, 147, 220, 164, 248, 83, 196, 80}

err := rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashBytes[:], signatureBytes)

if err != nil {
    fmt.Printf("err: %v\n", err)
} else {
    fmt.Printf("ok")
}

}

如果我在C#中使用下面的代码来验证签名,就可以了。

代码语言:javascript
运行
复制
        String publicKeyPemStr = @"-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCIw68jARnmvTh+xvMcv5iugtoH
Xt60NWEebfbghLTFuTlQvK0exY5hxnN/uD2UVc/S3QGnBQn0AfynhxlEZkedpYBb
5RWoVChGZMHu7hbZukMjByjxec0LjtuEQhY4m18XaVNmAQWD/EiROMGTghMwykkQ
+SBtx4Gl/O/BB6F4SQIDAQAB
-----END PUBLIC KEY-----";

        strReader = new StringReader(publicKeyPemStr);
        pemReader = new PemReader(strReader);
        RsaKeyParameters publicKey = (RsaKeyParameters)((AsymmetricKeyParameter)pemReader.ReadObject());

        sig = SignerUtilities.GetSigner("SHA256withRSA");
        sig.Init(false, publicKey);
        sig.BlockUpdate(hashBytes, 0, hashBytes.Length);

        if (sig.VerifySignature(signedBytes))
        {
            Console.WriteLine("Ok");
        }
        else
        {
            Console.WriteLine("NOK");
        }

        Console.ReadLine();

做了一些额外的测试,下面的Go代码生成了一个与C#代码完全不同的签名字符串,尽管私钥是相同的。有什么不同??

代码语言:javascript
运行
复制
func main() {
privKeyStr := `-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCIw68jARnmvTh+xvMcv5iugtoHXt60NWEebfbghLTFuTlQvK0e
xY5hxnN/uD2UVc/S3QGnBQn0AfynhxlEZkedpYBb5RWoVChGZMHu7hbZukMjByjx
ec0LjtuEQhY4m18XaVNmAQWD/EiROMGTghMwykkQ+SBtx4Gl/O/BB6F4SQIDAQAB
AoGAJLarODFee6OGG/paXvhMC2TTFLFyBVxjAuEwKdtWD9IGQdc0fhM4gqTccofJ
+B0FGiz7+ZMPtfImme5ZaRQv2wx7KOPbOdAyYxC7nLFCHYqDWZJ8/cCoS+hPJFd5
9OeGLGz3QKfEEPtYEAw4+E/UjilYAtRNREkISkYoB9Va8PUCQQDDHMPRSCfXbfZV
ufmlRZj2bH8sjVaSBbJIw+y9HKJ3ORRnKGjtIZ/+z70EwMwtbbQKnl71SruO5HB9
AUTtRka/AkEAs3GWQhplPbuH/fAlaEPy5GQilUNRt76NMsgtIFWPMXnt82cxTUUR
RIKwX7M96WBppPZ2Dy7uLrX8O+3fr6BK9wJATZ0lsBy57JKLiTJ/wmTbIjuqozhe
FZw6fYOiqt+3KSIFobuLcbkMgjp1AG0JS5D2K7swHvdpgMASl0dn+dMY1QJBAIPw
9QbN2bs2dJvnQ9oSfDoq1rLhuOheF/xK68Nmpc8/VBMwwTOLoVK6tWzoopFC7ur4
vX4Uh9WYwkpecab1OakCQD0SCs4zIggA/2NkUx8J5H07/drbm9uH+98EQUvzjTdz
qSW2jJPCA4GYYmtnnDRduukjmkJlbaaTdEH5YLCilF0=
-----END RSA PRIVATE KEY-----`

pemBlockPriv, _ := pem.Decode([]byte(privKeyStr))
privateKey, _ := x509.ParsePKCS1PrivateKey(pemBlockPriv.Bytes)

hashBytes := [32]byte{152, 154, 255, 19, 168, 20, 167, 43, 232, 133, 146, 13, 183, 80, 186, 85, 180, 249, 95, 142, 234, 71, 93, 188, 29, 147, 220, 164, 248, 83, 196, 80}

signatureByte, _ := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashBytes[:])
signatureStr := base64.StdEncoding.EncodeToString(signatureByte)

fmt.Printf("%v\n", signatureStr)
}
EN

Stack Overflow用户

回答已采纳

发布于 2017-02-07 15:59:30

当您使用sig.GenerateSignature()计算签名时,BouncyCastle会自动计算您的消息的sha256。应该传递给sig.BlockUpdate()的是希望sha256和rsa签名的消息。因此,从本质上讲,您已经在消息上使用了两次sha256。

你可以在这里看到这个:https://play.golang.org/p/mplEnmNbs9。在第27行,我在hashBytes上添加了另一个对sha256的调用,然后将其传递给rsa.VerifyPKCS1v15(),效果很好。

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42057466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档