如何将 JSON Web Key 转换为 Delphi 中的 PEM 格式?
How to convert JSON Web Key to PEM format in Delphi?
Earlier I found out that before using the signature in JWT Library,我需要将 JSON Web 密钥 (JWK) 转换为 PEM 格式。
JWK 格式的原始私钥:
{
"kty": "EC",
"d": "Rwyv99W3GnfjYbI0X-b5Umhvh88oRCKQkPxiwCPVGgg",
"crv": "P-256",
"x": "sDbcYT8HzBk1tUl849ZHrhpIn8ZV7HfD1DwYdsP1ip0",
"y": "EWodfKWQ6oE0ppyi7tRO_61BgAQsZyDjDGj9kLZiUts"
}
需要获取 PEM 格式,如下所示:
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIEcMr/fVtxp342GyNF/m+VJob4fPKEQikJD8YsAj1RoIoAoGCCqGSM49
AwEHoUQDQgAEsDbcYT8HzBk1tUl849ZHrhpIn8ZV7HfD1DwYdsP1ip0Rah18pZDq
gTSmnKLu1E7/rUGABCxnIOMMaP2QtmJS2w==
-----END EC PRIVATE KEY-----
有一个 online converter 可以满足我的需要。是否可以在 Delphi 中进行相同的转换?
您将在低级 OpenSSL 中获得所需的一切。
它的 API 有点神秘,但您可以使用 EC_POINT*() 函数来完成它。
检查我们在
mormot.crypt.openssl 使用低级 ECC 私钥并将它们与 OpenSSL 集成:
ecdsa_sign_osl
获取原始私钥并将其转换为 OpenSSL PEC_KEY
;
OpenSslSaveKeys
将此密钥保存为 PEM。
您只需导出 "d": "Rwyv99W3GnfjYbI0X-b5Umhvh88oRCKQkPxiwCPVGgg"
参数。它似乎与 TEccPrivateKey
中用作输入参数的布局相同 ecdsa_sign_osl()
.
您可能还会在 mormot.crypt.ecc256r1.pas.
中找到一些计算 ECC prime256v1 的纯 Pascal 代码
已找到解决方案。阅读详情 here.
简化示例:
uses
JSON,
EncdDecd;
function Base64urlToBase64(Base64urlStr: String): String;
begin
Result := StringReplace(Base64urlStr,'_','/', [rfReplaceAll]);
Result := StringReplace(Result,'-','+', [rfReplaceAll]);
end;
function JwkToPem(JWK: TJSONObject): String;
var
BinKey: TBytes;
begin
BinKey :=
[] + // ASN.1
[] + // Length of all following bytes (119 bytes)
[] + // Type (integer)
[] + // Length of integer (1 byte)
[] + // Value of integer (1)
[] + // Type (octet string)
[] + // Length of string (32 bytes)
DecodeBase64(Base64urlToBase64(JWK.Get('d').JsonValue.Value)) + // Private Key
[$A0] + // Tag 0
[[=10=]A] + // Length of tag (10 bytes)
[] + // Type (Object ID)
[] + // Length of the Object ID (8 bytes)
[A, , , $CE, D, , , ] + // - The object ID of the curve prime256v1
[$A1] + // Tag 1
[] + // Length of tag (68 bytes)
[] + // Type – Bit string
[] + // Length of the bit string (66 bytes)
[[=10=]] + // ???
[] + // Uncompressed Public Key
DecodeBase64(Base64urlToBase64(JWK.Get('x').JsonValue.Value))+ // Public Key X coord
DecodeBase64(Base64urlToBase64(JWK.Get('y').JsonValue.Value)); // Public Key Y coord
Result :=
'-----BEGIN EC PRIVATE KEY-----'+#13#10+
EncodeBase64(Pointer(BinKey), Length(BinKey))+#13#10+
'-----END EC PRIVATE KEY-----';
end;
Earlier I found out that before using the signature in JWT Library,我需要将 JSON Web 密钥 (JWK) 转换为 PEM 格式。
JWK 格式的原始私钥:
{
"kty": "EC",
"d": "Rwyv99W3GnfjYbI0X-b5Umhvh88oRCKQkPxiwCPVGgg",
"crv": "P-256",
"x": "sDbcYT8HzBk1tUl849ZHrhpIn8ZV7HfD1DwYdsP1ip0",
"y": "EWodfKWQ6oE0ppyi7tRO_61BgAQsZyDjDGj9kLZiUts"
}
需要获取 PEM 格式,如下所示:
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIEcMr/fVtxp342GyNF/m+VJob4fPKEQikJD8YsAj1RoIoAoGCCqGSM49
AwEHoUQDQgAEsDbcYT8HzBk1tUl849ZHrhpIn8ZV7HfD1DwYdsP1ip0Rah18pZDq
gTSmnKLu1E7/rUGABCxnIOMMaP2QtmJS2w==
-----END EC PRIVATE KEY-----
有一个 online converter 可以满足我的需要。是否可以在 Delphi 中进行相同的转换?
您将在低级 OpenSSL 中获得所需的一切。
它的 API 有点神秘,但您可以使用 EC_POINT*() 函数来完成它。
检查我们在 mormot.crypt.openssl 使用低级 ECC 私钥并将它们与 OpenSSL 集成:
ecdsa_sign_osl
获取原始私钥并将其转换为 OpenSSLPEC_KEY
;OpenSslSaveKeys
将此密钥保存为 PEM。
您只需导出 "d": "Rwyv99W3GnfjYbI0X-b5Umhvh88oRCKQkPxiwCPVGgg"
参数。它似乎与 TEccPrivateKey
中用作输入参数的布局相同 ecdsa_sign_osl()
.
您可能还会在 mormot.crypt.ecc256r1.pas.
中找到一些计算 ECC prime256v1 的纯 Pascal 代码已找到解决方案。阅读详情 here.
简化示例:
uses
JSON,
EncdDecd;
function Base64urlToBase64(Base64urlStr: String): String;
begin
Result := StringReplace(Base64urlStr,'_','/', [rfReplaceAll]);
Result := StringReplace(Result,'-','+', [rfReplaceAll]);
end;
function JwkToPem(JWK: TJSONObject): String;
var
BinKey: TBytes;
begin
BinKey :=
[] + // ASN.1
[] + // Length of all following bytes (119 bytes)
[] + // Type (integer)
[] + // Length of integer (1 byte)
[] + // Value of integer (1)
[] + // Type (octet string)
[] + // Length of string (32 bytes)
DecodeBase64(Base64urlToBase64(JWK.Get('d').JsonValue.Value)) + // Private Key
[$A0] + // Tag 0
[[=10=]A] + // Length of tag (10 bytes)
[] + // Type (Object ID)
[] + // Length of the Object ID (8 bytes)
[A, , , $CE, D, , , ] + // - The object ID of the curve prime256v1
[$A1] + // Tag 1
[] + // Length of tag (68 bytes)
[] + // Type – Bit string
[] + // Length of the bit string (66 bytes)
[[=10=]] + // ???
[] + // Uncompressed Public Key
DecodeBase64(Base64urlToBase64(JWK.Get('x').JsonValue.Value))+ // Public Key X coord
DecodeBase64(Base64urlToBase64(JWK.Get('y').JsonValue.Value)); // Public Key Y coord
Result :=
'-----BEGIN EC PRIVATE KEY-----'+#13#10+
EncodeBase64(Pointer(BinKey), Length(BinKey))+#13#10+
'-----END EC PRIVATE KEY-----';
end;