解决最初的问题“是否可以使用 ECC 私钥进行加密?”
通常用户会维护一个私钥并共享他们的公钥。公钥与私钥在数学上纠缠在一起,因此用公钥加密的消息可以用私钥解密。通过这种方式,私钥仍然是私有的!不建议使用私钥进行加密。如果您可以通过各种方式证明您希望这样做的理由,请解释。很高兴听到你的推理。但是,如果您正在学习并且不确定,请避免按照您的要求进行操作。
为了解决有关用于相互身份验证的私钥加密的声明......我不确定这将如何帮助提供相互身份验证,我真的很好奇 @comomind 在那里谈论什么。下面是一个关于 SSL/TLS 如何解决相互认证问题的链接:
(https://www.codeproject.com/Articles/326574/An-Introduction-to-Mutual-SSL-Authentication)
关于wolfCrypt问题的第二部分,wolfSSL的wolfCrypt库中的方法(或函数)是:
wc_ecc_encrypt
这是手册中描述此 API 和参数的部分:
(https://www.wolfssl.com/wolfSSL/Docs-wolfssl-manual-18-14-wolfcrypt-api-ecc.html)
wc_ecc_encrypt
简介:
包含头文件:wolfssl/wolfcrypt/ecc.h
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx);
描述:此函数对来自 msg 的给定输入消息进行加密
出去。此函数将可选的 ctx 对象作为参数。什么时候
提供,加密基于 ecEncCtx 的 encAlgo 进行,
kdfAlgo 和 macAlgo。如果未提供 ctx,则处理完成
使用默认算法 ecAES_128_CBC、ecHKDF_SHA256 和
ecHMAC_SHA256。
此功能要求消息根据
ctx 指定的加密类型。
返回值:0:成功加密输入后返回
消息 BAD_FUNC_ARG:如果 privKey、pubKey、msg、msgSz、out 或
outSz 为 NULL,或者 ctx 对象指定了不受支持的加密
type BAD_ENC_STATE_E:如果给定的 ctx 对象处于状态则返回
不适合加密 BUFFER_E:如果
提供的输出缓冲区太小,无法存储加密的密文
MEMORY_E:如果为
共享密钥
参数: privKey - 指向包含
用于加密的私钥 pubKey - 指向 ecc_key 的指针
对象包含一个希望与之建立对等点的公钥
将 msg- 指针传递给保存要加密的消息的缓冲区
msgSz - 要加密的缓冲区的大小 - 指向缓冲区的指针
用于存储加密密文 outSz - 指向 word32 的指针
包含输出缓冲区中可用大小的对象。之上
成功加密消息,保存写入的字节数
到输出缓冲区 ctx - 可选:指向 ecEncCtx 对象的指针
指定要使用的不同加密算法
例子:
byte msg[] = { /* initialize with msg to encrypt. Ensure
padded to block size */ };
byte out[sizeof(msg)]; word32 outSz = sizeof(out);
int ret;
ecc_key cli, serv; // initialize cli with
private key // initialize serv with received public key
ecEncCtx* cliCtx, servCtx; // initialize cliCtx and servCtx //
exchange salts
ret = wc_ecc_encrypt(&cli, &serv, msg, sizeof(msg), out, &outSz,
cliCtx);
if(ret != 0) { // error encrypting message }
另见:wc_ecc_decrypt
请注意,此 API 接受公钥和私钥,其中公钥来自对等方,私钥是您自己的私钥。然后,此 API 将使用 ECDH 生成共享密钥。共享密钥应该用于加密和解密。您尝试与之交谈的一方也将使用您的公钥和他的私钥来生成他自己的共享密钥。任何一方都不会通过网络发送共享的秘密。在此处查看有关共享机密主题的更多信息:(https://crypto.stackexchange.com/questions/21169/how-does-ecdh-arrive-on-a-shared-secret)
测试用例:
(https://github.com/wolfSSL/wolfssl/blob/master/wolfcrypt/test/test.c#L8701)
#ifdef HAVE_ECC_ENCRYPT
int ecc_encrypt_test(void)
{
WC_RNG rng;
int ret;
ecc_key userA, userB;
byte msg[48];
byte plain[48];
byte out[80];
word32 outSz = sizeof(out);
word32 plainSz = sizeof(plain);
int i;
ret = wc_InitRng(&rng);
if (ret != 0)
return -3001;
wc_ecc_init(&userA);
wc_ecc_init(&userB);
ret = wc_ecc_make_key(&rng, 32, &userA);
ret += wc_ecc_make_key(&rng, 32, &userB);
if (ret != 0)
return -3002;
for (i = 0; i < 48; i++)
msg[i] = i;
/* encrypt msg to send to userB */
ret = wc_ecc_encrypt(&userA, &userB, msg, sizeof(msg), out, &outSz, NULL);
if (ret != 0)
return -3003;
/* userB decrypt the message received from userA */
ret = wc_ecc_decrypt(&userB, &userA, out, outSz, plain, &plainSz, NULL);
if (ret != 0)
return -3004;
if (XMEMCMP(plain, msg, sizeof(msg)) != 0)
return -3005;
{ /* let's verify message exchange works, A is client, B is server */
ecEncCtx* cliCtx = wc_ecc_ctx_new(REQ_RESP_CLIENT, &rng);
ecEncCtx* srvCtx = wc_ecc_ctx_new(REQ_RESP_SERVER, &rng);
byte cliSalt[EXCHANGE_SALT_SZ];
byte srvSalt[EXCHANGE_SALT_SZ];
const byte* tmpSalt;
if (cliCtx == NULL || srvCtx == NULL)
return -3006;
/* get salt to send to peer */
tmpSalt = wc_ecc_ctx_get_own_salt(cliCtx);
if (tmpSalt == NULL)
return -3007;
XMEMCPY(cliSalt, tmpSalt, EXCHANGE_SALT_SZ);
tmpSalt = wc_ecc_ctx_get_own_salt(srvCtx);
if (tmpSalt == NULL)
return -3007;
XMEMCPY(srvSalt, tmpSalt, EXCHANGE_SALT_SZ);
/* in actual use, we'd get the peer's salt over the transport */
ret = wc_ecc_ctx_set_peer_salt(cliCtx, srvSalt);
ret += wc_ecc_ctx_set_peer_salt(srvCtx, cliSalt);
ret += wc_ecc_ctx_set_info(cliCtx, (byte*)"wolfSSL MSGE", 11);
ret += wc_ecc_ctx_set_info(srvCtx, (byte*)"wolfSSL MSGE", 11);
if (ret != 0)
return -3008;
/* get encrypted msg (request) to send to B */
outSz = sizeof(out);
ret = wc_ecc_encrypt(&userA, &userB, msg, sizeof(msg), out, &outSz,cliCtx);
if (ret != 0)
return -3009;
/* B decrypts msg (request) from A */
plainSz = sizeof(plain);
ret = wc_ecc_decrypt(&userB, &userA, out, outSz, plain, &plainSz, srvCtx);
if (ret != 0)
return -3010;
if (XMEMCMP(plain, msg, sizeof(msg)) != 0)
return -3011;
{
/* msg2 (response) from B to A */
byte msg2[48];
byte plain2[48];
byte out2[80];
word32 outSz2 = sizeof(out2);
word32 plainSz2 = sizeof(plain2);
for (i = 0; i < 48; i++)
msg2[i] = i+48;
/* get encrypted msg (response) to send to B */
ret = wc_ecc_encrypt(&userB, &userA, msg2, sizeof(msg2), out2,
&outSz2, srvCtx);
if (ret != 0)
return -3012;
/* A decrypts msg (response) from B */
ret = wc_ecc_decrypt(&userA, &userB, out2, outSz2, plain2, &plainSz2,
cliCtx);
if (ret != 0)
return -3013;
if (XMEMCMP(plain2, msg2, sizeof(msg2)) != 0)
return -3014;
}
/* cleanup */
wc_ecc_ctx_free(srvCtx);
wc_ecc_ctx_free(cliCtx);
}
/* cleanup */
wc_ecc_free(&userB);
wc_ecc_free(&userA);
wc_FreeRng(&rng);
return 0;
}
#endif /* HAVE_ECC_ENCRYPT */