имеет проблемы импортирующих ключи, созданные с помощью PHP OpenSSL для CryptoAPIНевозможно импортировать ключи RSA, созданные с помощью PHP OpenSSL для окон CryptoAPI
Я успешно создать пару ключей в PHP, крипта/не расшифровывает строку с ним - нет проблем
<?php
$privateKey = openssl_pkey_new(array(
'private_key_bits' => 1024,
'private_key_type' => OPENSSL_KEYTYPE_RSA));
openssl_pkey_export($privateKey, $s);
$info = openssl_pkey_get_details($privateKey);
$public = openssl_pkey_get_public($info['key']);
$private = openssl_pkey_get_private($s);
$s = '';
$s1 = '';
openssl_public_encrypt('bla bla bla', $s, $public);
openssl_private_decrypt($s, $s1, $private);
echo('$s.'<br>'.$s1);
?>
Затем я написал программу в Delphi, которая должна импортировать частные и открытые ключи в CryptoAPI. Я нашел некоторый пример частного ключа RSA в Интернете, и он импортирует с моим кодом отлично, но когда я пытаюсь импортировать ключ, сгенерированный с помощью моего php-кода, он не работает на CryptDecodeObjectEx с «asn1 bad tag value met» Ошибка. Клавиши очень похожи, за исключением того PHP генерирует немного длиннее ключ, чем я нашел в примере Интернет, хотя они оба 1024 бит ...
php generated key (does not work):
priv_key: string =
'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN/NfimL4/8Pmp7+' +
'j299I7yaT6SpF1jwrFlwlLLjDibehqjBOcao+CaLK8Se+hysqZGGwr2walUprGxG' +
'Z5hnfCQCOchbTs5CiXnBCIX1aPKaRMx/SX3b4moT+wnkLrGOnHnUM+2c+jqZUjdh' +
'06hwlv1LCVcCtTW9NWU3Qi3G+r9bAgMBAAECgYBjjuSK0uJP+r8L764bKI4XPoYj' +
'd90dAaOJ/h0IHx2SiPdaZuqux0fszYhg5V/aFa0xQcOr4qjKzckYOZGoKJD+FtCq' +
'bNBEg1eZsKWYVJvTO8N2H0Lx4VSCiG7PjiqLGFfsmXZDXLPXhzsuCOUACmfcVoqh' +
'NlXOEAKtaTZI+uAakQJBAPB8sIQN7xTgCQcP2F8IbWR3VRAlnr4LWZQ5k96uxWjC' +
'wC6R8c7NnvUj+Fzs3XMXR8e3aTRme9OyHAWy7ReO+scCQQDuPUjBXXxuYGQq4ho5' +
'Pq4QEtHNKECDNDtKBaLvr9r7aXYOfMM/XiXqFqHAZqcrTRtMXD1sUhg4o+vIYkrg' +
'5qLNAkEA6+Z0RGVitAh78ohxh+89V4LTV05/5A5AJe1BBvxLu1LmsAgLuf/rwK4z' +
'L/xN0lrw15EryvII34VkhZaZijV/+wJAfX52xrTSCOppmVVE7wafdgQT0/fyE6r9' +
'2D4j2BJQTcL91x/NUaHsYuTNC6aHRH33dT/ZcyfDboKafxGX0+RpuQJBAMdPGszm' +
'JYhD9F8kz+Q9R04iuwupLxUU6Q60yVVZxRDBQ7OLxBQwrHa2WQ0TA8WC73TMNaph' +
'VN4ayHJHK8shjt0=';
example key (works fine and it is shorter than php key):
priv_key: string =
'MIICXAIBAAKBgQCf6YAJOSBYPve1jpYDzq+w++8YVoATI/YCi/RKZaQk+l2ZfoUQ' +
'g0qrYrfkzeoOa/qd5VLjTTvHEgwXnlDXMfo+vSgxosUxDOZXMTBqJGOViv5K2QBv' +
'k8A1wi4k8tuo/7OWya29HvcfavUk3YXaV2YFe8V6ssaZjNcVWmDdjqNkXwIDAQAB' +
'AoGALrd+ijNAOcebglT3ioE1XpUbUpbir7TPyAqvAZUUESF7er41jY9tnwgmBRgL' +
'Cs+M1dgLERCdKBkjozrDDzswifFQmq6PrmYrBkFFqCoLJwepSYdWnK1gbZ/d43rR' +
'2sXzSGZngscx0CxO7KZ7xUkwENGd3+lKXV7J6/vgzJ4XnkECQQDTP6zWKT7YDckk' +
'We04hbhHyBuNOW068NgUUvoZdBewerR74MJx6nz28Tp+DeNvc0EveiQxsEnbV8u+' +
'NRkX5y0xAkEAwcnEAGBn5kJd6SpU0ALA9XEpUv7tHTAGQYgCRbfTT59hhOq6I22A' +
'ivjOCNG9c6E7EB2kcPVGuCpYUhy7XBIGjwJAK5lavKCqncDKoLwGn8HJdNcyCIWv' +
'q5iFoDw37gTt1ricg2yx9PzmabkDz3xiUmBBNeFJkw/FToXiQRGIakyGIQJAJIem' +
'PPPvYgZssYFbT4LVYO8d/Rk1FWVyKHQ9CWtnmADRXz7oK7l+m7PfEuaGsf9YpOcR' +
'koGJ/TluQLxNzUNQnQJBAImwr/yYFenIx3HQ6UX/fCt6qpGDv0VfOLyR64MNeegx' +
'o7DhNxHbFkIGzk4lKhMKcHKDrawZbdJtS9ie2geSwVQ=';
кода в Delphi, который импортирует ключ:
var
dwBufferLen, cbKeyBlob, i: longword;
pbBuffer, pbKeyBlob: pointer;
hProv: HCRYPTPROV;
hKey: HCRYPTKEY;
begin
hProv := 0;
hKey := 0;
// convert key string to a binary
if not(CryptStringToBinary(PWideChar(priv_key), 0, 1, nil, @dwBufferLen, nil, nil)) then
exit;
GetMem(pbBuffer, dwBufferLen);
if not(CryptStringToBinary(PWideChar(priv_key), 0, 1, pbBuffer, @dwBufferLen, nil, nil)) then
exit;
// convert binary to a key blob
if not(CryptDecodeObjectEx(X509_ASN_ENCODING or PKCS_7_ASN_ENCODING,
PKCS_RSA_PRIVATE_KEY, pbBuffer, dwBufferLen, 0, nil, nil, @cbKeyBlob)) then
begin
// first key generates error here
ShowMessage(SysErrorMessage(GetLastError));
exit;
end;
GetMem(pbKeyBlob, cbKeyBlob);
if not(CryptDecodeObjectEx(X509_ASN_ENCODING or PKCS_7_ASN_ENCODING,
PKCS_RSA_PRIVATE_KEY, pbBuffer, dwBufferLen, 0, nil, pbKeyBlob, @cbKeyBlob)) then
exit;
if not(CryptAcquireContext(@hProv, nil, MS_ENHANCED_PROV, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT)) then
exit;
if not(CryptImportKey(hProv, pbKeyBlob, cbKeyBlob, 0, 0, @hKey)) then
exit;
//...
if hKey <> 0 then
CryptDestroyKey(hKey);
if hProv <> 0 then
CryptReleaseContext(hProv, 0);
end;
Вы пытались понять, что отличается между двумя разными ключами (что может объяснить, почему функция Windows API жалуется). Вы должны декодировать кодированный ключ Base64/ASN.1. SO даже дает подсказку о том, как декодировать документ ASN.1 здесь: http://stackoverflow.com/questions/5153059/any-asn1-implementation-in-delphi –
Спасибо за ваш комментарий, я проверил их и посмотрел, что php Сгенерированный ключ добавляет дополнительные поля по сравнению с ключом CryptoAPI. Есть ли у вас какие-либо идеи о том, как создавать PHP-ключи без добавления дополнительной информации? Может быть, некоторые флаги переданы openssl_pkey_new? Эта функция недостаточно хорошо документирована. –