2016-12-19 3 views
0

이 코드와 ECDSA 서명을 확인하려면 :UWP ECDSP는 서명

AsymmetricKeyAlgorithmProvider objAsymmAlgProv = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.EcdsaSha256); 
CryptographicKey keypair = objAsymmAlgProv.CreateKeyPairWithCurveName(EccCurveNames.SecP256r1); 
BinaryStringEncoding encoding = BinaryStringEncoding.Utf8; 
buffMsg = CryptographicBuffer.ConvertStringToBinary("Test Message", encoding); 
IBuffer buffSIG = CryptographicEngine.Sign(keypair, buffMsg); 
byte [] SignByteArray = buffSIG.ToArray(); 
bool res = CryptographicEngine.VerifySignature(keypair, buffMsg, buffSIG); 

VerifySignature 항상 true를 반환하고이 괜찮습니다.

하지만 서명에 문제가 있습니다.

왜 서명 길이 (SignByteArray)가 고정되어 있습니까? (0x40 바이트).

SignByteArray [0]SignByteArray [2] 값이 올바르지 않은 이유는 무엇입니까? (나는 그들이 0x30에해야한다고 생각하고는 0x02)

나는 ECDSA 사양 쌍 (r, s)이 서명 것을 결정과 결론 https://kjur.github.io/jsrsasign/sample-ecdsa.html

답변

3

같은 일을 예상했다. 그것이 게을리하는 것은 사람들이 그것을 어떻게 써야 하는지를 나타내는 것입니다.

Windows 및 .NET은 big-endian r concat big-endian s 인 IEEE (P) 1363 형식을 사용합니다. rs은 동일한 크기 (키 크기로 결정됨)이므로 서명의 길이는 항상 고르고 r은 전반입니다.

OpenSSL은 SEQUENCE (INTEGER (r), INTEGER (s)) 인 ASN.1/DER 인코딩을 사용합니다. DER 인코딩은 6 바이트 (degenerate r = 0, s = 0에서 30 04 02 00 02 00)까지 계속 진행할 수 있으며 평균적으로 IEEE 형식보다 6 바이트 더 큽니다. 30 [length, one or more bytes] 02 [length, one or more bytes] [optional padding 00] [big-endian r with no leading 00s] 02 [length, one or more bytes] [optional padding 00] [big-endian s with no leading 00s]으로 인코딩됩니다.

DER 양식은 너무 구체적으로 설명하는 데이터에 의존하므로 예제가 도움이됩니다. 우리는 32 비트 필드에서 곡선을 사용한다고 가정하고 (r = 1016, s = 2289644760) 생성합니다.

IEEE 1363 :

// r 
00 00 03 F8 
// s 
88 79 34 D8 

DER :

SEQUENCE(INTEGER(1016), INTEGER(2289644760)) 

// Encode r 
// 1016 => 0x3F8 => 03 F8 (length 02) 
SEQUENCE(
    02 02 
     03 F8, 
    INTEGER(2289644760)) 

// Encode s 
// 2289644760 => 0x887934D8 => 88 79 34 D8 
// But since the high bit is set this is a negative number (-2005322536), 
// and s is defined to be positive. So insert a 00 to ensure the high bit is clear. 
// => 00 88 79 34 D8 (length 05) 
SEQUENCE(
    02 02 
     03 F8 
    02 05 
     00 88 79 34 D8) 

// And encode the sequence, whose payload length we can now count as 11 (0B) 
30 0B 
    02 02 
     03 F8 
    02 05 
     00 88 79 34 D8 

그래서 윈도우/.NET 00 00 03 F8 88 79 34 D8을 방출하고, OpenSSL을가 30 0B 02 02 03 F8 02 05 00 88 79 34 D8을 방출한다. 그러나 그들은 둘 다 단지 (r, s) = (1016, 2289644760)이라고 말하고 있습니다.

(DER 인코딩의 signature [2] == 0x02는 작업중인 크기 키에 맞지만 496 비트 키 주위에서는 SEQUENCE 길이가 통계적으로 더 많이 필요하게됩니다 1 바이트보다 많으므로 P-521 키의 경우 03 81 88 02 바이트로 시작하여 88 바이트의 변동 가능성이 가장 높습니다.

+0

이것이 내가 원하는 것입니다! 고마워요! –