Encryption 如何在Delphi中将JSON Web密钥转换为PEM格式?

Encryption 如何在Delphi中将JSON Web密钥转换为PEM格式?,encryption,pem,delphi-10.2-tokyo,jwk,Encryption,Pem,Delphi 10.2 Tokyo,Jwk,在中使用签名之前,我需要将JSON Web密钥(JWK)转换为PEM格式 JWK格式的原始私钥: { "kty": "EC", "d": "Rwyv99W3GnfjYbI0X-b5Umhvh88oRCKQkPxiwCPVGgg", "crv": "P-256", "x": "sDbcYT8HzBk1tUl849ZHrhpIn8ZV7

在中使用签名之前,我需要将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-----

有一个能满足我需要的。是否可以在Delphi中进行相同的转换?

在低级OpenSSL中,您将拥有所需的一切

它的API有点神秘,但是你有EC_POINT*()函数来完成它

看看我们在这里做了什么 要使用低级ECC私钥并将其与OpenSSL集成,请执行以下操作:

  • ecdsa_-sign_-osl
    它接受原始私钥并将其转换为OpenSSL
    PEC_-key
  • OpenSslSaveKeys
    将此密钥另存为PEM
只需导出
“d”:“Rwyv99W3GnfjYbI0X-b5Umhvh88oRCKQkPxiwCPVGgg”
参数。它的布局似乎与
ecdsa\u sign\u osl()
中用作输入参数的
tecprivatekey
相同


您还可以在中找到一些计算ECC prime256v1的纯pascal代码。

找到了解决方案。阅读细节

简化示例:

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 :=

  [$30] + // ASN.1
  [$77] + // Length of all following bytes (119 bytes)

  [$02] + // Type (integer)
  [$01] + // Length of integer (1 byte)
  [$01] + // Value of integer (1)

  [$04] + // Type (octet string)
  [$20] + // Length of string (32 bytes)
  DecodeBase64(Base64urlToBase64(JWK.Get('d').JsonValue.Value)) +  // Private Key

  [$A0] + // Tag 0
  [$0A] + // Length of tag (10 bytes)
  [$06] + // Type (Object ID)
  [$08] + // Length of the Object ID (8 bytes)
  [$2A, $86, $48, $CE, $3D, $03, $01, $07] + // - The object ID of the curve prime256v1

  [$A1] + // Tag 1
  [$44] + // Length of tag (68 bytes)
  [$03] + // Type – Bit string
  [$42] + // Length of the bit string (66 bytes)
  [$00] + // ???
  [$04] + // 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;

@Bouchez
TecPrivateKey
类型的大小为32字节。如何将
“d”:“Rwyv99W3GnfjYbI0X-b5Umhvh88oRCKQkPxiwCPVGgg”
放入此参数?它似乎是用“d”编码的base-64-uri。好的,我从base64解码了此参数,实际得到了32个字节。函数的第二个参数--
Hash
如何处理?它也是32字节。这是什么?这是256位哈希,它正在签名。顾名思义。我怀疑如果你不能弄明白这一点,你可能会在旅途中迷路。也许值得阅读一些关于ECDSA工作原理的文档。