2017-02-05 8 views
0

BouncyCastle을 사용하고 Go에서 서명의 유효성을 검사하여 C#에서 RSA 서명을 생성합니다.RSA SHA256 서명 생성 및 유효화

그러나 C# 프로그램의 서명은 Go에서 유효성을 검사하지 않습니다.

상세 :

대중/개인 키 쌍 해시 바이트 배열 SHA265를 이용하여 생성 및 간략화를 위해 하드 코딩되는 것이다 Online RSA Key Generator

으로부터 생성 한 예이다.

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();    
    } 

이 서명을 검증하는 내 이동 코드를 생성합니다. 나는

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#으로 다음 코드를 사용하는 경우, 그것은 괜찮 변수 서명에 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 코드를 수정했다. –

+1

나는 Go의 공개 키와 개인 키를 사용하여 해쉬 된 메시지에 서명하고 확인하려고 시도했으며 작동합니다. 하드 코딩 된 'signatureStr'은 틀린 것 같습니다. –

답변

1

당신이 sig.GenerateSignature에 서명을 계산할 때 BouncyCastle 자동으로 메시지의 SHA256을 계산합니다(). sig.BlockUpdate()에 전달해야하는 것은 sha256과 rsa가 서명 한 메시지입니다. 따라서 본질적으로 sha256을 메시지에 두 번 사용했습니다.

여기에서 확인할 수 있습니다. https://play.golang.org/p/mplEnmNbs9. 27 번째 줄에서는 hashBytes에 sha256에 대한 또 다른 호출을 추가 한 다음이를 rsa.VerifyPKCS1v15()에 전달하여 정상적으로 작동합니다.

+0

감사합니다! 이것은 날 동안 나를 괴롭혔다. .... –