使用wolfCrypt实现ECIES椭圆曲线和对称密钥

本文介绍了使用wolfCrypt库实现ECIES(Elliptic Curve Integrated Encryption Scheme,椭圆曲线集成加密方案)的方法,展示了如何利用椭圆曲线密码学中的公钥来导出对称密钥以进行加密和解密操作,并提供了C代码示例和相关的密钥生成、加密解密过程。

使用 wolfCrypt 的 ECIES 椭圆曲线和对称密钥

我正在研究一系列 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 生成的密钥相同。该方法如下图所示:

WolfSSL/WolfCrypt 实现

为此,我们集成了 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 开发的示例:

  • wolfSSL 和哈希wolfSSL and Hashing。wolfSSL 集成了一个 CSharp (C#) 封装器,并允许访问 C++ 代码。这包括 wolfCrypt 对 ECC (ECDSA/ECDHE)、ECIES、RSA、ED25519/Curve25519、AES-GCM 和 HASH 密码算法的支持。在本例中,我们将实现 SHA256、SHA384、SHA512 和 SHA3 的哈希方法。总的来说,wolfSSL 符合 FIPS 140–3 标准。我们需要与这些 DLL 集成 [ here]。
  • wolfSSL 和 ECDSAwolfSSL and ECDSA。ECDSA 已经存在了二十多年,最早在 [1] 中提出。与基于 RSA 的 DSA 方法相比,ECDSA 方法显著提高了签名消息的性能。它使用椭圆曲线方法加快了整个过程,并支持更小的密钥大小。它的桂冠是被 Satoshi Nakamoto 选中用于他的比特币协议,然后被采用到以太坊中。在这种情况下,我们将使用 wolfSSL/wolfCrypt 生成一个 ECC 密钥对,然后对消息的哈希进行签名,然后验证它。
  • wolfSSL 和 ECIESwolfSSL and ECIES。使用 ECIES(椭圆曲线集成加密方案),我们使用椭圆曲线密码学的公钥来派生对称密钥。
  • 原文链接: medium.com/asecuritysite...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
asecuritysite
asecuritysite
江湖只有他的大名,没有他的介绍。