openssl使用gcm模式解密,iv12字节,c实现
时间: 2024-04-29 11:27:14 浏览: 201
为了使用openssl库中的GCM模式解密,需要使用以下代码:
```c
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
int DecryptGCM(unsigned char *ciphertext, int ciphertext_len, unsigned char *aad,
int aad_len, unsigned char *key, unsigned char *iv, int iv_len,
unsigned char *plaintext)
{
EVP_CIPHER_CTX *ctx;
int len;
int plaintext_len;
int ret;
/* Create and initialise the context */
if(!(ctx = EVP_CIPHER_CTX_new())) return -1;
/* Initialise the decryption operation using GCM mode */
if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL))
return -1;
/* Set IV length */
if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
return -1;
/* Initialise key and IV */
if(1 != EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) return -1;
/* Provide any associated data */
if(aad_len > 0)
{
if(1 != EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len))
return -1;
}
/* Decrypt ciphertext */
if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
return -1;
plaintext_len = len;
/* Set expected tag value */
if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, ciphertext + ciphertext_len))
return -1;
/* Finalise the decryption */
ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
/* Clean up */
EVP_CIPHER_CTX_free(ctx);
if(ret > 0) plaintext_len += len;
else return -1;
return plaintext_len;
}
```
其中,参数ciphertext是要解密的数据,ciphertext_len是密文的长度,aad是associated data,aad_len是associated data的长度,key是密钥,iv是初始向量,iv_len是初始向量的长度,plaintext是解密后的明文。
例如,要解密一个长度为ciphertext_len的加密后的消息,可以使用以下代码:
```c
unsigned char ciphertext[ciphertext_len]; /* 加密后的消息 */
unsigned char *aad = NULL; /* associated data */
int aad_len = 0; /* associated data的长度 */
unsigned char key[16]; /* 密钥 */
unsigned char iv[12]; /* 初始向量 */
unsigned char plaintext[ciphertext_len];
int plaintext_len = DecryptGCM(ciphertext, ciphertext_len, aad, aad_len, key, iv, 12, plaintext);
if(plaintext_len < 0)
{
/* 解密失败 */
}
else
{
/* 解密成功 */
}
```
需要注意的是,当解密失败时,DecryptGCM函数会返回一个负数。如果解密成功,函数会返回解密后的明文的长度(即plaintext_len)。
希望这个回答可以帮助你解决问题!
阅读全文