暗号化次世代API(CNG)を使用してECDHEを実装しています。公開鍵と秘密鍵を生成します。事前共有キーの場合、私は事前共有鍵秘密ハンドル(BCRYPT_SECRET_HANDLE)を返しますBCryptSecretAgreement APIを使用します。BYTE配列として共有秘密情報をBCRYPT_SECRET_HANDLEからエクスポートする
事前共有キーをBYTE配列としてBCRYPT_SECRET_HANDLEからエクスポートするにはどうすればよいですか?
暗号化次世代API(CNG)を使用してECDHEを実装しています。公開鍵と秘密鍵を生成します。事前共有キーの場合、私は事前共有鍵秘密ハンドル(BCRYPT_SECRET_HANDLE)を返しますBCryptSecretAgreement APIを使用します。BYTE配列として共有秘密情報をBCRYPT_SECRET_HANDLEからエクスポートする
事前共有キーをBYTE配列としてBCRYPT_SECRET_HANDLEからエクスポートするにはどうすればよいですか?
BCRYPT_SECRET_HANDLE
を入手したら、BCryptDeriveKey
を使用して実際の対称暗号化キーを取得します。
BCryptSecretAgreement
を呼び出した後、BCryptDeriveKey
関数を使用して共有秘密情報を取得する必要があります。次のように
これを行うことができます。
// generates an ECDH shared secret from a public key and a private key
int get_ECDH_key(BCRYPT_KEY_HANDLE pubkey, BCRYPT_KEY_HANDLE privkey, unsigned char **key,
unsigned int *keylen)
{
SECURITY_STATUS sstatus;
BCRYPT_SECRET_HANDLE secret;
int _len;
// creates the shared secret, stored in a BCRYPT_SECRET_HANDLE
sstatus = BCryptSecretAgreement(privkey, pubkey, &secret, 0);
if (!BCRYPT_SUCCESS(sstatus)) {
printf("BCryptSecretAgreement failed with status %d", sstatus);
return 0;
}
// find out how much space is needed before retrieving the shared secret
sstatus = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, NULL, NULL, 0, &_len, 0);
if (!BCRYPT_SUCCESS(sstatus)) {
printf("BCryptDeriveKey failed with status %d", sstatus);
return 0;
}
// allocate space for the shared secret
*key = malloc(_len);
if (*key == NULL) {
perror("malloc failed");
exit(1);
}
// retrieve the shared secret
sstatus = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, NULL, *key, _len,
keylen, 0);
if (!BCRYPT_SUCCESS(sstatus)) {
printf("BCryptDeriveKey failed with status %d", sstatus);
return 0;
}
return 1;
}
二番目のパラメータについては、一定のBCRYPT_KDF_HASH
は鍵導出関数としてハッシュを使用することを言います。使用するハッシュは、3番目のパラメータで指定できます。この例では、3番目のパラメータはNULLであるため、デフォルトでSHA1が使用されています。
また、キーを受け取るバッファへのポインタである4番目のパラメータはNULLにすることができます。その場合、キーはコピーされませんが、コピーされるバイト数は6番目のパラメータで指定されたアドレスに書き込まれます。これにより、適切な量の領域を割り当ててから、関数を再度呼び出すことができます。今回は、割り当てられたバッファのアドレスを渡します。
これは実際に元の質問には答えません。これが行わないのは、実際に共有キーを抽出することです。それは共有の秘密から何かを派生させますが、共有された鍵そのものを実際に取得する方法はないようです。 –
@TomQuarendonこのコードは、実際には共有秘密情報を取得します。 'BCryptDeriveKey'への2回目の呼び出しの後、共有キーを表す' * key'に '* keylen'バイトがあります。交換機の両側は、それぞれの秘密鍵ともう一方の公開鍵を使用して同じ値を持ちます。 – dbush
* a *共有キーを取得します。たとえば、Diffie Hellmanの場合はそうではありませんが、「g ** xy mod p」の答えが得られます。せいぜい、プリペンドとアペンドを指定しないと、その値のSHA1ハッシュが得られます。たとえば、DHのJava実装と互換性があり、SSHなどの仕様に従って互換性のあるものを作成しようとしている場合、あなたは不運です。あなたは "null"キー導出関数を指定することができない限り、私はこれまでこれまで失敗しています。 –
これは実際に元の質問には答えません。これが行わないのは、実際に共有キーを抽出することです。それは共有の秘密から何かを派生させますが、共有された鍵そのものを実際に取得する方法はないようです。 –