2016-12-19 2 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を返し、これはokです。

しかし、私は署名にいくつかの問題があります。

署名の長さ(SignByteArray)が固定されているのはなぜですか? (0x40バイト)。

SignByteArray [0]SignByteArray [2]の値が正しくないのはなぜですか? (私は彼らが0x30からすべきだと思いますし、0x02の)

私はECDSAの仕様はペア(rs)が署名されていることを決意して結論https://kjur.github.io/jsrsasign/sample-ecdsa.html

答えて

3

のようなものを期待していました。それが怠るのは、どのように書き留めなければならないかを示すことです。

Windowsおよび.NETはビッグエンディアンコンカットビッグエンディアンsであるIEEE(P)1363形式を使用します。 rsは同じサイズ(キーサイズで決まる)なので、署名の長さは常に偶数であり、rは前半です。

OpenSSLは、SEQUENCE(INTEGER(r)、INTEGER(s))であるASN.1/DERエンコーディングを使用します。 DERエンコーディングは、縮退したr = 0、s = 0の場合には6バイト(30 04 02 00 02 00、縮退r = 0、s = 0)まで完全に行え、平均して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 

ので、Windowsは/ .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キーの場合、88バイトのばらつきを持つ03 81 88 02として開始する可能性が最も高いです。

+0

これはまさに私が探していたものです!どうもありがとう! –