使用OpenSSL aes ccm代码错误

时间:2016-10-28 06:10:35

标签: openssl aes cbc-mode aes-gcm cbc-mac

这是aes-ccm示例代码。 我使用c语言打开我的视觉工作室。 但它不起作用。我认为问题点是void handleErrors(void); 怎么能解决这个问题?请给我推荐。 谢谢

#include <openssl/conf.h>
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>

void handleErrors(void)
{
ERR_print_errors_fp(stderr);
abort();
}

int encryptccm(unsigned char *plaintext, int plaintext_len, unsigned char *aad,
int aad_len, unsigned char *key, unsigned char *iv,
unsigned char *ciphertext, unsigned char *tag)
{
EVP_CIPHER_CTX *ctx;

int len;

int ciphertext_len;

/* Create and initialise the context */
if (!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

/* Initialise the encryption operation. */
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_192_ccm(), NULL, NULL, NULL))
    handleErrors();

/* Setting IV len to 7. Not strictly necessary as this is the default
* but shown here for the purposes of this example */
if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, 7, NULL))
    handleErrors();

/* Set tag length */
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, 14, NULL);

/* Initialise key and IV */
if (1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) handleErrors();

/* Provide the total plaintext length
*/
if (1 != EVP_EncryptUpdate(ctx, NULL, &len, NULL, plaintext_len))
    handleErrors();

/* Provide any AAD data. This can be called zero or one times as
* required
*/
if (1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len))
    handleErrors();

/* Provide the message to be encrypted, and obtain the encrypted output.
* EVP_EncryptUpdate can only be called once for this
*/
if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
    handleErrors();
ciphertext_len = len;

/* Finalise the encryption. Normally ciphertext bytes may be written at
* this stage, but this does not occur in CCM mode
*/
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
ciphertext_len += len;

/* Get the tag */
if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, 14, tag))
    handleErrors();

/* Clean up */
EVP_CIPHER_CTX_free(ctx);

return ciphertext_len;
}

int decryptccm(unsigned char *ciphertext, int ciphertext_len, unsigned char *aad,
int aad_len, unsigned char *tag, unsigned char *key, unsigned char *iv,
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())) handleErrors();

/* Initialise the decryption operation. */
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_192_ccm(), NULL, NULL, NULL))
    handleErrors();

/* Setting IV len to 7. Not strictly necessary as this is the default
* but shown here for the purposes of this example */
if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, 7, NULL))
    handleErrors();

/* Set expected tag value. */
if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, 14, tag))
    handleErrors();

/* Initialise key and IV */
if (1 != EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) handleErrors();


/* Provide the total ciphertext length
*/
if (1 != EVP_DecryptUpdate(ctx, NULL, &len, NULL, ciphertext_len))
    handleErrors();

/* Provide any AAD data. This can be called zero or more times as
* required
*/
if (1 != EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len))
    handleErrors();

/* Provide the message to be decrypted, and obtain the plaintext output.
* EVP_DecryptUpdate can be called multiple times if necessary
*/
ret = EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len);

plaintext_len = len;

/* Clean up */
EVP_CIPHER_CTX_free(ctx);

if (ret > 0)
{
    /* Success */
    return plaintext_len;
}
else
{
    /* Verify failed */
    return -1;
}
}

int main(void)
{
/* Set up the key and iv. Do I need to say to not hard code these in a
* real application? :-)
*/

/* A 256 bit key */
unsigned char *key = (unsigned char *)"01234567890123456789012345678901";

/* A 128 bit IV */
unsigned char *iv = (unsigned char *)"01234567890123456";
/* Message to be encrypted */
unsigned char *plaintext =
    (unsigned char *)"The quick brown fox jumps over the lazy dog";

/* Buffer for ciphertext. Ensure the buffer is long enough for the
* ciphertext which may be longer than the plaintext, dependant on the
* algorithm and mode
*/
unsigned char ciphertext[2048];
/*unsigned char ciphertext[2048];*/
/* Buffer for the decrypted text */
unsigned char decryptedtext[2048];

int decryptedtext_len, ciphertext_len;

/* Initialise the library */
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
OPENSSL_config(NULL);

/* Encrypt the plaintext */
ciphertext_len = encryptccm(plaintext, strlen((char *)plaintext), key, NULL, NULL, iv, ciphertext,  NULL);
    /* Do something useful with the ciphertext here */
    printf("Ciphertext is:\n");
BIO_dump_fp(stdout, (const char *)ciphertext, ciphertext_len);

/* Decrypt the ciphertext */
decryptedtext_len = decryptccm(ciphertext, ciphertext_len, key,NULL, NULL, iv,
    decryptedtext, NULL);

/* Add a NULL terminator. We are expecting printable text */
decryptedtext[decryptedtext_len] = '\0';

/* Show the decrypted text */
printf("Decrypted text is:\n");
printf("%s\n", decryptedtext);

/* Clean up */
EVP_cleanup();
ERR_free_strings();

return 0;
}

0 个答案:

没有答案