2017-02-05 6 views
0

Я генерирую RSA-подпись на C#, используя BouncyCastle и проверяя подпись в Go.Генерация и проверка подписи RSA SHA256

Но по какой-то причине подпись из программы C# не будет проверяться в Go.

Детали:

Общественность/частного пара ключей является примером генерируется из Online RSA Key Generator

Массив хэш байт является тот, который генерируется с использованием SHA265 и зашиты для простоты.

Я пробовал разные алгоритмы подписки для BouncyCastle, играл с парами ключей, но ничего не работает.

Я также подтверждено, что массив байтов подписи матчей между этими двумя языками ...

Может кто-нибудь сказать мне, что я здесь отсутствует? Или, по крайней мере, как исследовать дальше?

Мой 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") 
} 

}

Если я использую следующий код в 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

Вам не хватает шага декодирования base64 в вашей программе Go. –

+0

Да, вы были правы. мой пример кода был неправильным, но у меня была базовая кодировка в фактическом коде. но до сих пор не решает мою проблему. Я изменил код go, чтобы включить его сейчас. –

+1

Я попытался подписать и подтвердить ваше хеш-сообщение, используя ваши общедоступные и закрытые ключи в Go, и он работает. Кажется, что жестко закодированная 'signatureStr' неверна. –

ответ

1

BouncyCastle автоматически рассчитает SHA256 вашего сообщения при вычислении подписи с sig.GenerateSignature(). Что вы должны передать в sig.BlockUpdate() - это сообщение, которое вы хотите подписать sha256 и rsa. Поэтому, по сути, вы дважды использовали sha256 в своем сообщении.

Вы можете увидеть это здесь: https://play.golang.org/p/mplEnmNbs9. В строке 27 я добавил еще один вызов sha256 на ваш hashBytes, а затем передал его в rsa.VerifyPKCS1v15() и отлично работает.

+0

Спасибо! Меня это раздражало в течение нескольких дней ... –

Смежные вопросы