我正在构建一个 Web API,我需要实现 ECDH 来执行端到端加密。在服务器端我有一个 C# 应用程序,在客户端我有一个 Javascript 应用程序。
我能够交换密钥、生成私钥并加密消息,但我在解密时遇到了问题。
我认为问题在于公钥的交换。在 javascript 中,键以字节“4”开头,.NET 键以 8 个字节开头,用于标识键的类型和大小,我需要更改这些字节以导入每个键(我在这里找到的信息)。也许这会导致一些不一致。
在客户端,我使用 Web Cryptography API 来处理 ECDH。我正在实施如下。
生成密钥
await window.crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-256",
},
false,
["deriveKey", "deriveBits"]
);
像这样导出公钥:
await window.crypto.subtle.exportKey(
"raw",
publicKey
);
导入外部公钥
await window.crypto.subtle.importKey(
"raw",
{
name: "ECDH",
namedCurve: "P-256",
},
false,
["deriveKey", "deriveBits"]
)
最后推导出密钥
await window.crypto.subtle.deriveKey(
{
name: "ECDH",
namedCurve: "P-256",
public: publicKey,
},
privateKey,
{
name: "AES-CBC",
length: 256,
},
false,
["encrypt", "decrypt"]
)
在服务器端,我正在实施以下相同的步骤。生成公钥
private static ECDiffieHellmanCng ecdh = new ECDiffieHellmanCng(256);
public static void GeneratePublicKey()
{
ecdh.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
ecdh.HashAlgorithm = CngAlgorithm.Sha256;
publicKey = ecdh.PublicKey.ToByteArray();
}
导出公钥。请注意,我更改了第一个字节
public static byte[] GetPublicKey()
{
var auxKey = publicKey.Skip(7).ToArray();
auxKey[0] = 4;
return auxKey;
}
导入公钥并导出私钥。请注意,我更改了第一个字节
public static void GerarChavePrivada(byte[] bobPublicKey)
{
byte[] aux = new byte[bobPublicKey.Length + 7];
aux[0] = 0x45;
aux[1] = 0x43;
aux[2] = 0x4B;
aux[3] = 0x31;
aux[4] = 0x20;
aux[5] = 0x00;
aux[6] = 0x00;
aux[7] = 0x00;
for (int i = 1; i < bobPublicKey.Length; i++)
{
aux[7 + i] = bobPublicKey[i];
}
var importedKey = CngKey.Import(aux, CngKeyBlobFormat.EccPublicBlob);
privateKey = ecdh.DeriveKeyMaterial(importedKey);
}
qq_笑_17
天涯尽头无女友
FFIVE
相关分类