2017-02-05 23 views
0

BouncyCastleを使用してC#でRSA署名を生成し、Goで署名を検証しています。RSA SHA256署名の生成と検証

しかし、何らかの理由でC#プログラムの署名がGoで検証されません。

詳細:

公開/秘密鍵ペアがハッシュバイト配列がSHA265を使用して生成され、単純化のためにハードコードされているものであるOnline RSA Key Generator

から生成された一例です。

私はBouncyCastleのさまざまな署名アルゴリズムを試してみましたが、キーペアで再生しましたが、何も動作していないようです。私も署名のバイト配列が2つの言語間で一致していることを検証してきました

...

誰もが私がここで行方不明です何を教えてもらえますか?または、少なくともさらに調査する方法は?

私のC#のコード署名

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#コードの結果をコピー可変

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") 
} 

}

Iは、署名を検証するためにC#で次のコードを使用する場合、それは結構です。

 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#コードとは全く異なる署名文字列を生成します。違いはどこですか?

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) 
} 
+0

Goプログラムでbase64デコードステップが欠落しています。 –

+0

はい、あなたは正しいです。私のコード例は正しくありませんでしたが、私は実際のコードではbase64エンコーディングを持っていました。残念ながら私の問題は解決しません。 go codeを修正して今すぐ追加しました。 –

+1

Goの公開鍵と秘密鍵を使ってハッシュされたメッセージに署名して検証しようとしました。ハードコードされた 'signatureStr'は間違っているようです。 –

答えて

1

あなたはsig.GenerateSignatureで署名を計算する際にはBouncyCastleが自動的にあなたのメッセージのSHA256を計算します()。あなたがsig.BlockUpdate()に渡すべきことはsha256とrsaが署名したいメッセージです。だから本質的にあなたのメッセージにsha256を2回使用しました。

これはここに表示されます:https://play.golang.org/p/mplEnmNbs9。 27行目で、あなたのhashBytesにsha256という別の呼び出しを追加し、それをrsa.VerifyPKCS1v15()に渡して正常に動作しました。

+0

ありがとうございます!これは数日間私を悩ませている.... –