加密++和压缩的EC密钥

时间:2013-05-15 23:06:26

标签: c++ crypto++

如何在Crypto ++中生成压缩的ECDSA密钥?

AutoSeededRandomPool prng;
ECDSA<ECP, SHA1>::PrivateKey privateKey;
ECDSA<ECP, SHA1>::PublicKey publicKey;
privateKey.Initialize( prng, CryptoPP::ASN1::secp256r1());

const Integer& x1 = privateKey.GetPrivateExponent();
cout << "priv:  " << std::hex << x1 << endl;
privateKey.MakePublicKey( publicKey );
const ECP::Point& q = publicKey.GetPublicElement();
const Integer& qx = q.x;
const Integer& qy = q.y;
cout << "pub x: " << std::hex << qx << endl;
cout << "pub y: " << std::hex << qy << endl;

此代码生成密钥对并打印公钥的X和Y组件。

我需要知道是否有办法打印压缩密钥的Y分量,或者是否需要从未压缩的y分量生成它。如果我需要生成它,有人可以链接我对如何使用Integer类的一个很好的解释吗?

1 个答案:

答案 0 :(得分:4)

  

如何在CryptoPP中生成压缩的ECDSA密钥?

您不创建压缩密钥。您生成一个公钥,然后压缩它,如果这是必需的。来自Crpyto ++用户组的How to construct a public ECDSA key with point compression turned on?

ECDSA<ECP, SHA1>::Verifier verifier(...);
verifier.AccessKey().AccessGroupParameters().SetPointCompression(true); 

在您的情况下,它将是:

publicKey.AccessGroupParameters().SetPointCompression(true);

因为verifier.AccessKey()返回ECDSA公钥。


  

我需要知道是否有办法打印压缩密钥的Y分量

压缩是一种演示文稿格式选项或优化。您无法使用压缩在序列化密钥上打印Y组件,因为它不存在(请参阅下面的ASN.1转储)。

压缩打开时,Y“速记”将变为1或-1,具体取决于组件的符号(符号表示该点所在的象限)。这个想法是有人向你发送{1,X}对或{-1,X}对,你可以解决Y,因为你知道它应该在哪个象限。如果Y只允许为正,你只需要序列化{X}(而不是{-1,X}或{1,X})。 (我没有深入研究书籍或标准,因此这里可能会有一些勘误表。)


  

...或者如果我需要从未压缩的y组件生成它。如果我需要生成它,有人可以链接我对如何使用Integer类的一个很好的解释吗?

我不知道你在这里谈论的是什么。点压缩会影响演示。如果你打开点压缩并获取Y,你仍然会得到Y.您无法计算压缩点。你需要X和Y坐标。


将以下内容添加到您的程序中:

publicKey.AccessGroupParameters().SetPointCompression(false);
ByteQueue q1;
publicKey.Save(q1);
cout << "Uncompressed size: " << dec << q1.MaxRetrievable() << endl;

publicKey.AccessGroupParameters().SetPointCompression(true);
ByteQueue q2;
publicKey.Save(q2);
cout << "Compressed size: " << dec << q2.MaxRetrievable() << endl;

以下是我输出的内容:

$ ./cryptopp-test.exe
priv:  4ce30d22d9593d9c7f4406eda1ce0740c7486106374d0abe7e352e1d5b1d5622h
pub x: 41a9bc936b6d1dd3a1ded997d7da08f1df990e9b50f9b58e9e4fd9319758ea34h
pub y: 4ad39ffb79c402063a99ecbc0cac8fde606db6764ace90933feee5f8d65937a2h
Uncompressed size: 311
Compressed size: 246

如果在打开点压缩后获取Y,则仍会得到4ad39ffb79c402063a99ecbc0cac8fde606db6764ace90933feee5f8d65937a2h,因为压缩会影响显示。


现在,添加以下内容以转储未压缩和压缩的密钥:

FileSink fs1("key-1.der", true);
q1.TransferTo(fs1);

FileSink fs2("key-2.der", true);
q2.TransferTo(fs2);

密钥以ASN.1的DER编码转储,并符合Certicom的SEC 1: Elliptic Curve Cryptography(在较小程度上,ANSI 9.62RFC 5480, ECC SubjectPublicKeyInfo Format - 请参阅下面的Field Element {{1 }} vs OCTET STRING)。

你可以在他们身上运行Peter Gutmann的dumpasn1

BIT STRING

注意差异:

$ dumpasn1.exe key-1.der 
  0 307: SEQUENCE {
  4 236:   SEQUENCE {
  7   7:     OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1)
 16 224:     SEQUENCE {
 19   1:       INTEGER 1
 22  44:       SEQUENCE {
 24   7:         OBJECT IDENTIFIER prime-field (1 2 840 10045 1 1)
 33  33:         INTEGER
       :           00 FF FF FF FF 00 00 00 01 00 00 00 00 00 00 00
       :           00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF
       :           FF
       :         }
 68  68:       SEQUENCE {
 70  32:         OCTET STRING
       :           FF FF FF FF 00 00 00 01 00 00 00 00 00 00 00 00
       :           00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FC
104  32:         OCTET STRING
       :           5A C6 35 D8 AA 3A 93 E7 B3 EB BD 55 76 98 86 BC
       :           65 1D 06 B0 CC 53 B0 F6 3B CE 3C 3E 27 D2 60 4B
       :         }
138  65:       OCTET STRING
       :         04 6B 17 D1 F2 E1 2C 42 47 F8 BC E6 E5 63 A4 40
       :         F2 77 03 7D 81 2D EB 33 A0 F4 A1 39 45 D8 98 C2
       :         96 4F E3 42 E2 FE 1A 7F 9B 8E E7 EB 4A 7C 0F 9E
       :         16 2B CE 33 57 6B 31 5E CE CB B6 40 68 37 BF 51
       :         F5
205  33:       INTEGER
       :         00 FF FF FF FF 00 00 00 00 FF FF FF FF FF FF FF
       :         FF BC E6 FA AD A7 17 9E 84 F3 B9 CA C2 FC 63 25
       :         51
240   1:       INTEGER 1
       :       }
       :     }
243  66:   BIT STRING
       :     04 41 A9 BC 93 6B 6D 1D D3 A1 DE D9 97 D7 DA 08
       :     F1 DF 99 0E 9B 50 F9 B5 8E 9E 4F D9 31 97 58 EA
       :     34 4A D3 9F FB 79 C4 02 06 3A 99 EC BC 0C AC 8F
       :     DE 60 6D B6 76 4A CE 90 93 3F EE E5 F8 D6 59 37
       :     A2
       :   }

$ dumpasn1.exe key-2.der 
  0 243: SEQUENCE {
  3 204:   SEQUENCE {
  6   7:     OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1)
 15 192:     SEQUENCE {
 18   1:       INTEGER 1
 21  44:       SEQUENCE {
 23   7:         OBJECT IDENTIFIER prime-field (1 2 840 10045 1 1)
 32  33:         INTEGER
       :           00 FF FF FF FF 00 00 00 01 00 00 00 00 00 00 00
       :           00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF
       :           FF
       :         }
 67  68:       SEQUENCE {
 69  32:         OCTET STRING
       :           FF FF FF FF 00 00 00 01 00 00 00 00 00 00 00 00
       :           00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FC
103  32:         OCTET STRING
       :           5A C6 35 D8 AA 3A 93 E7 B3 EB BD 55 76 98 86 BC
       :           65 1D 06 B0 CC 53 B0 F6 3B CE 3C 3E 27 D2 60 4B
       :         }
137  33:       OCTET STRING
       :         03 6B 17 D1 F2 E1 2C 42 47 F8 BC E6 E5 63 A4 40
       :         F2 77 03 7D 81 2D EB 33 A0 F4 A1 39 45 D8 98 C2
       :         96
172  33:       INTEGER
       :         00 FF FF FF FF 00 00 00 00 FF FF FF FF FF FF FF
       :         FF BC E6 FA AD A7 17 9E 84 F3 B9 CA C2 FC 63 25
       :         51
207   1:       INTEGER 1
       :       }
       :     }
210  34:   BIT STRING
       :     02 41 A9 BC 93 6B 6D 1D D3 A1 DE D9 97 D7 DA 08
       :     F1 DF 99 0E 9B 50 F9 B5 8E 9E 4F D9 31 97 58 EA
       :     34
       :   }

# key-1.der
243  66:   BIT STRING
       :     04 41 A9 BC 93 6B 6D 1D D3 A1 DE D9 97 D7 DA 08
       :     F1 DF 99 0E 9B 50 F9 B5 8E 9E 4F D9 31 97 58 EA
       :     34 4A D3 9F FB 79 C4 02 06 3A 99 EC BC 0C AC 8F
       :     DE 60 6D B6 76 4A CE 90 93 3F EE E5 F8 D6 59 37
       :     A2

第一个有两个整数编码,而第二个有一个整数编码。常见值为# key-2.der 210 34: BIT STRING : 02 41 A9 BC 93 6B 6D 1D D3 A1 DE D9 97 D7 DA 08 : F1 DF 99 0E 9B 50 F9 B5 8E 9E 4F D9 31 97 58 EA : 34 : } ,这是您的41 A9 BC 93 ... 97 58 EA 34以上。来自key-2的缺失字符串是pub x,那就是上面的4A D3 9F FB ... D6 59 37 A2。为了完整性,值被编码为{X,Y}或{X},而不是ASN.1的整数编码。

最后的差异是BIT STRING的第一个八位字节:02与04(或03)。 04表示其未压缩点。来自RFC 5480,第2.2节:

pub y

在查看标准和2.2节之后,Crypto ++可能有一个错误:它写了一个 The first octet of the OCTET STRING indicates whether the key is compressed or uncompressed. The uncompressed form is indicated by 0x04 and the compressed form is indicated by either 0x02 or 0x03 (see 2.3.3 in [SEC1]). The public key MUST be rejected if any other value is included in the first octet. ,但标准清楚地讨论了BIT STRING

编辑1 :看来这也是ANSI 9.62下的加密++错误。 6.2节,有限域元素和椭圆曲线点的语法(p.20)

OCTET STRING

编辑2 :Crypto ++使用Certicom的SEC 1: Elliptic Curve Cryptography指定的格式。附录C(第77页)指出:

    A finite field element shall be represented by a value of type FieldElement:
      FieldElement ::= OCTET STRING
    The value of FieldElement shall be the octet string representation of a field
    elementfollowing the conversion routine in Section 4.3.1.
    An elliptic curve point shall be represented by a value of type ECPoint:
      ECPoint ::= OCTET STRING