提问者:小点点

椭圆曲线Diffie Hellman公钥大小


我想使用Diffie hellman在c#Server和c Client之间生成密钥。此代码为服务器生成公钥:

        serverECDH = new ECDiffieHellmanCng(ECCurve.NamedCurves.nistP256);
        serverECDH.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
        serverECDH.HashAlgorithm = CngAlgorithm.Sha256; 
        ECDHPublicKey =Convert.ToBase64String(serverECDH.PublicKey.ToByteArray());
        Console.WriteLine(serverECDH.KeySize); //256
        Console.WriteLine(serverECDH.PublicKey.ToByteArray().Length); //72
        Console.WriteLine(ECDHPublicKey);

我想知道为什么public Key Byte Array Size是72,而我期望是64字节长的数组?此外,这是我在Client中生成公钥的实现:

if (NULL == (pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) HandleErrors(1);
if (1 != EVP_PKEY_paramgen_init(pctx)) HandleErrors(2);
if (1 != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1)) HandleErrors(3);

if (!EVP_PKEY_paramgen(pctx, &params)) HandleErrors(4);
if (NULL == (kctx = EVP_PKEY_CTX_new(params, NULL))) HandleErrors(5);

if (1 != EVP_PKEY_keygen_init(kctx)) HandleErrors(6);
if (1 != EVP_PKEY_keygen(kctx, &pkey)) HandleErrors(7);

bio = BIO_new(BIO_s_mem());
PEM_write_bio_PUBKEY(bio, pkey);
int publicKeyLen = BIO_pending(bio);
cout << publicKeyLen << endl;
unsigned char* publicKeyChar = (unsigned char*)malloc(publicKeyLen);
BIO_read(bio, publicKeyChar, publicKeyLen);

ECDHPublicKey =  string(reinterpret_cast<char const*>(publicKeyChar),publicKeyLen);
cout << ECDHPublicKey << endl;

在这段代码中,公钥长度是128字节(字符?)这又是奇怪的,因为我指定NID_X9_62_prime256v1曲线。我的错误在哪里?此外,NID_X9_62_prime256v1和nistP256在c和c#中匹配吗?

编辑:这是cout的一个例子

-----BEGIN PUBLIC KEY-----MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUFD9ZNby6x2bf/VC16/NHSxIXdit Ips60uLoi0/jKmbmMHRg2xbXVzV8Uc1DElMlZA817bMFCnVvi1VsM5JYg==

-----结束公钥-----


共1个答案

匿名用户

在C代码中,公钥不仅DER编码,还经过PEM编码。这在base 64编码的DER结构周围添加了页眉和页脚。PEM用于基于文本的接口,其中二进制数据可能会失真。因此,它有时也被称为“ASCII装甲”(或“ASCII装甲”,具体取决于您的方言)。

如果您想查看C/OpenSSL代码的结构,只需将base 64编码的DER结构粘贴到此站点或使用openssl asn1parse

serverECDH. PublicKey.ToByteArray()返回的Mickeysoft结构似乎由"ECK1"20 00 00后跟两个静态大小的编码坐标(可以是大端或小端)组成。ECK1可能是椭圆曲线键格式1-无论它是什么-并且20 00 00可能是八位字节中的键/坐标大小,为32*8=256。请注意,C#正式使用平台endianess,因此20 00 00是一个32位的小端值。可能您需要一个外部库来编码它们的键,以便任何其他运行时都可以理解它们。

至于你的标签问题:是的,ANS(I)X9.62 prime256r1曲线与NISTP-256和secp256r1相同,因为(我认为)最初是由认证公司定义的。曲线首先被定义,然后被拾取