本文介绍了使用wolfCrypt库实现ECIES(Elliptic Curve Integrated Encryption Scheme,椭圆曲线集成加密方案)的方法,展示了如何利用椭圆曲线密码学中的公钥来导出对称密钥以进行加密和解密操作,并提供了C代码示例和相关的密钥生成、加密解密过程。
我正在研究一系列 wolfSSL/wolfCrypt 库,它们都通过了 FIPS 140–3 认证。因此,如果你对密码学非常重视,wolfCrypt 是实现密码学代码的最佳库之一。
你是否知道 GCHQ 使用 ECIES(椭圆曲线集成加密方案)方法来开发其 COVID-19 跟踪应用程序?使用 ECIES(椭圆曲线集成加密方案),我们使用椭圆曲线密码学的公钥来派生对称密钥。在这种方法中,Alice 生成一个随机私钥(dA),然后取椭圆曲线上的一个点(G)并确定她的公钥(QA):
因此,G 和 QA 是椭圆曲线上的点。然后,Alice 将 QA 发送给 Bob。接下来,Bob 将生成:
其中 r 是 Bob 生成的随机数。然后,对称密钥 (S) 用于加密消息。Alice 将收到加密的消息以及 R。然后,她可以确定与 Bob 相同的加密密钥,如下所示:
即:
这与 Bob 生成的密钥相同。该方法如下图所示:
为此,我们集成了 C# 封装器 (wolfSSL_CSharp.dll) 和主 wolfssl.dll [ here ],以及一个示例解决方案 [ here]:
namespace wolfSSL
{
using System;
using System.Text;
using wolfSSL.CSharp;
class Program
{
private static string toHex(byte[] s)
{
return (BitConverter.ToString(s).Replace("-", ""));
}
static void Main(string[] args)
{
int bufferSize = wolfcrypt.MAX_ECIES_TEST_SZ;
string message = "Test";
byte[] salt = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
int keySize = 32;
IntPtr AlicePublicKey = IntPtr.Zero;
IntPtr AlicePrivateKey = IntPtr.Zero;
IntPtr AlicePrivateCtx = IntPtr.Zero;
IntPtr AlicePublicCtx = IntPtr.Zero;
IntPtr rng = IntPtr.Zero;
IntPtr heap = IntPtr.Zero;
if (args.Length > 0) message = args[0];
if (args.Length > 1) keySize = System.Convert.ToInt32(args[1]);
byte[] plaintext = new byte[bufferSize];
byte[] encrypted = new byte[bufferSize];
byte[] decrypted = new byte[bufferSize];
/* Random context (随机上下文) */
rng = wolfcrypt.RandomNew();
/* Create keys (创建密钥) */
AlicePublicKey = wolfcrypt.EccMakeKey(keySize, rng);
AlicePrivateKey = wolfcrypt.EccMakeKey(keySize, rng);
byte[] AlicePublicKeyDer;
var ret = wolfcrypt.EccExportPrivateKeyToDer(AlicePublicKey, out AlicePublicKeyDer);
byte[] AlicePrivateKeyDer;
ret = wolfcrypt.EccExportPrivateKeyToDer(AlicePrivateKey, out AlicePrivateKeyDer);
/* Context creation (上下文创建) */
AlicePrivateCtx = wolfcrypt.EciesNewCtx((int)wolfcrypt.ecFlags.REQ_RESP_CLIENT, rng, heap);
AlicePublicCtx = wolfcrypt.EciesNewCtx((int)wolfcrypt.ecFlags.REQ_RESP_SERVER, rng, heap);
/* Set context salt (设置上下文盐) */
var rtn= wolfcrypt.EciesSetKdfSalt(AlicePrivateCtx, salt);
rtn= wolfcrypt.EciesSetKdfSalt(AlicePublicCtx, salt);
Array.Clear(plaintext, 0, plaintext.Length);
Array.Copy(Encoding.ASCII.GetBytes(message), plaintext, message.Length);
int plaintextLen = ((message.Length + (wolfcrypt.AES_BLOCK_SIZE - 1)) /wolfcrypt.AES_BLOCK_SIZE) * wolfcrypt.AES_BLOCK_SIZE;
/* Encrypt message (加密消息) */
ret = wolfcrypt.EciesEncrypt(AlicePrivateKey, AlicePublicKey, plaintext, (uint)plaintextLen, encrypted, AlicePrivateCtx);
/* Decrypt message (解密消息) */
ret = wolfcrypt.EciesDecrypt(AlicePublicKey, AlicePrivateKey, encrypted, (uint)ret, decrypted, AlicePublicCtx);
var len = message.Length;
var msg = System.Text.Encoding.ASCII.GetString(decrypted).Substring(0, len);
Console.WriteLine($"Key size: {keySize}");
Console.WriteLine($"Message: {message}");
Console.WriteLine($"Alice Public Key: {toHex(AlicePublicKeyDer)}");
Console.WriteLine($"Alice Private Key: {toHex(AlicePrivateKeyDer)}");
Console.WriteLine($"Encrypted: {BitConverter.ToString(encrypted).Replace("-", "")}");
Console.WriteLine($"Decrypted: {msg}");
if (AlicePublicKey != IntPtr.Zero) wolfcrypt.EccFreeKey(AlicePublicKey);
if (AlicePrivateKey != IntPtr.Zero) wolfcrypt.EccFreeKey(AlicePrivateKey);
if (AlicePrivateCtx != IntPtr.Zero) wolfcrypt.EciesFreeCtx(AlicePrivateCtx);
if (AlicePublicCtx != IntPtr.Zero) wolfcrypt.EciesFreeCtx(AlicePublicCtx);
if (rng != IntPtr.Zero) wolfcrypt.RandomFree(rng);
}
}
}
一个演示 here,以及一个示例运行如下:
Key size: 16
Message: Hello1231klklkl
Alice Public Key: 302A020101041CA5A5433B76E26F6FB216FD0BA1E140C720CD826A142D483F1E19A82CA00706052B81040021
Alice Private Key: 302A020101041C18FC394A5AD3AC9D0B0DBD43EBA6E2648048218717BC7D4B6430FA2EA00706052B81040021
Encrypted: 04334EB2460B32A553CD69582D2754FD71549F8E62465203AB505AFAAF9B9ED42A728250DCAFECE6FE6A25C94BC1C3D260D277D43B9DA6384C386E658986EF1834311C1BF3926608F11DEA6911CFC1C774C9E21E138666F5E93B7F7223819AFF25D773DD8E1BCE469E0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Decrypted: Hello1231klklkl
如果我们解析公钥,我们得到 [ here]:
DER: 302A020101041CA5A5433B76E26F6FB216FD0BA1E140C720CD826A142D483F1E19A82CA00706052B81040021
[U] SEQUENCE (30)
[U] INTEGER (02): 1
[U] OCTET STRING: 0xb'A5A5433B76E26F6FB216FD0BA1E140C720CD826A142D483F1E19A82C'
Private key: a5a5433b76e26f6fb216fd0ba1e140c720cd826a142d483f1e19a82c
[C] 0x0
[U] OBJECT (06): 1.3.132.0.33 - secp224r1
-----BEGIN PUBLIC KEY-----
MCoCAQEEHKWlQzt24m9vshb9C6HhQMcgzYJqFC1IPx4ZqCygBwYFK4EEACE=
-----END PUBLIC KEY-----
我们可以看到我们有一个 secp224r1 曲线。对于私钥 [ here]:
DER: 302A020101041C18FC394A5AD3AC9D0B0DBD43EBA6E2648048218717BC7D4B6430FA2EA00706052B81040021
[U] SEQUENCE (30)
[U] INTEGER (02): 1
[U] OCTET STRING: 0xb'18FC394A5AD3AC9D0B0DBD43EBA6E2648048218717BC7D4B6430FA2E'
Private key: 18fc394a5ad3ac9d0b0dbd43eba6e2648048218717bc7d4b6430fa2e
[C] 0x0
[U] OBJECT (06): 1.3.132.0.33 - secp224r1
-----BEGIN PUBLIC KEY-----
MCoCAQEEHBj8OUpa06ydCw29Q+um4mSASCGHF7x9S2Qw+i6gBwYFK4EEACE=
-----END PUBLIC KEY-----
对于一个 256 位的密钥,我们得到 [ here]:
Key size: 32
Message: Hello
Alice Public Key: 30310201010420807AA2AE0AB7B2B1E66EAADFD7E63470EC5DEF29EBCC65BC379B60278725DD9AA00A06082A8648CE3D030107
Alice Private Key: 303102010104209A0509913EA958D48EE2F43CDAB442E0A14048BE62686604E151DC2F45E33D84A00A06082A8648CE3D030107
Encrypted: 04808E94426617837F921EB6A11EEF3D630A8D936BF10BFA13525668FF544CB320552A745F9FFE5680C90B971B31B23102EC59879AF87A0A582A7A0C8A006B285C6D4EAF738D14A15EB699747E3E0FA709F086F5C793393918BFDFD6B5E41E7404AFB9EA1DF707FE9C6505F14FA58E6EE6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Decrypted: Hello
对于公钥,我们得到 [ here]:
DER: 30310201010420807AA2AE0AB7B2B1E66EAADFD7E63470EC5DEF29EBCC65BC379B60278725DD9AA00A06082A8648CE3D030107
[U] SEQUENCE (30)
[U] INTEGER (02): 1
[U] OCTET STRING: 0xb'807AA2AE0AB7B2B1E66EAADFD7E63470EC5DEF29EBCC65BC379B60278725DD9A'
Private key: 807aa2ae0ab7b2b1e66eaadfd7e63470ec5def29ebcc65bc379b60278725dd9a
[C] 0x0
[U] OBJECT (06): 1.2.840.10045.3.1.7 - secp256r1
-----BEGIN PUBLIC KEY-----
MDECAQEEIIB6oq4Kt7Kx5m6q39fmNHDsXe8p68xlvDebYCeHJd2aoAoGCCqGSM49AwEH
-----END PUBLIC KEY-----
在这里我们可以看到我们正在使用 secp256k1 曲线。
以下是我为 wolfCrypt 开发的示例:
- 原文链接: medium.com/asecuritysite...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!