C,AES_cbc_decrypt从解密中丢失字节

时间:2015-06-23 02:28:57

标签: c encryption openssl cryptography

我总是丢失最后一部分,这里是我的代码,即使它使用scrypt,那部分工作正常,我已经测试了超过500字节的散列。

所以我产生一个32字节的散列(对于AES256),一个16字节的iv和一个16字节的salt,当然还有我加密文本的长度,这些文本将按照这个顺序保存在初始化中。

1 ......... 16 .. 16 .. 16 * x
[长度] [盐] [iv] [加密数据]

解密字符串的长度是可以的,但问题是长数据不能完全解密,较短的数据可以很好地工作。

你可以完全跳过这里的scrypt部分,因为它已经过很多测试,但我不认为错误是存在的,因为我看到了部分数据。

#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <openssl/bio.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include "libscrypt.h"

#define VK_SCRYPT_N 16384
#define VK_SCRYPT_r 8
#define VK_SCRYPT_p 1

#define VK_SCRYPT_HASH_LEN 32
#define VK_SCRYPT_SALT_LEN 16
#define VK_SCRYPT_LEN 48

int scryptencrypt(uint8_t* plaintext,size_t plaintext_l,uint8_t* password,size_t password_l,uint8_t* cipher){
    int saltRet;
    int hashRet;

    uint8_t saltbuf[VK_SCRYPT_SALT_LEN];
    saltRet = libscrypt_salt_gen(saltbuf,VK_SCRYPT_SALT_LEN);

    if (saltRet == -1) {
        return 1;
    } else {

        uint8_t hashbuf[VK_SCRYPT_HASH_LEN];
        int hashRet = libscrypt_scrypt(password,password_l,saltbuf,
                VK_SCRYPT_SALT_LEN,VK_SCRYPT_N, VK_SCRYPT_r, VK_SCRYPT_p, hashbuf, VK_SCRYPT_HASH_LEN);

        if (hashRet != 0) {
            return 1;
        } else {

            unsigned char iv[AES_BLOCK_SIZE];
            int rand_st = RAND_bytes(iv, AES_BLOCK_SIZE);
            if (rand_st <= 0){
                return 1;
            }

            const size_t result_len = ((plaintext_l + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;

            unsigned char encrypted[result_len];
            memset(encrypted, 0, sizeof(encrypted));

            AES_KEY key;
            if(AES_set_encrypt_key((unsigned char*) &hashbuf, 256, &key) >= 0){

                memcpy(cipher, &plaintext_l,1);
                memcpy(cipher + 1, &saltbuf, VK_SCRYPT_SALT_LEN);
                memcpy(cipher + 1 + VK_SCRYPT_SALT_LEN, &iv, AES_BLOCK_SIZE);

                AES_cbc_encrypt(plaintext,encrypted,plaintext_l, (const AES_KEY *) &key, iv, AES_ENCRYPT);
                memcpy(cipher + 1 + VK_SCRYPT_SALT_LEN + AES_BLOCK_SIZE, &encrypted, result_len);

                return 0;
            } else {
                return 1;
            }
        }
    }
}

int scryptdecrypt(uint8_t* cipher,size_t cipher_l,uint8_t* password,size_t password_l,uint8_t* plaintext){

    uint8_t saltbuf[VK_SCRYPT_SALT_LEN];
    uint8_t hashbuf[VK_SCRYPT_HASH_LEN];
    unsigned char iv[AES_BLOCK_SIZE];

    uint8_t length = 0;
    memcpy(&length,cipher,1);
    memcpy(saltbuf,cipher + 1,VK_SCRYPT_SALT_LEN);
    memcpy(iv,cipher + 1 + VK_SCRYPT_SALT_LEN,AES_BLOCK_SIZE);

    int hashRet = libscrypt_scrypt(password,password_l,(uint8_t*)saltbuf,
            VK_SCRYPT_SALT_LEN,VK_SCRYPT_N, VK_SCRYPT_r, VK_SCRYPT_p, hashbuf, VK_SCRYPT_HASH_LEN););

    if (hashRet != 0) {
        return 1;
    } else {
        AES_KEY key;
        if (AES_set_decrypt_key((unsigned char*) &hashbuf, 256, &key) >= 0){

            AES_cbc_encrypt(cipher + 1 + VK_SCRYPT_SALT_LEN + AES_BLOCK_SIZE, plaintext, length,
                &key, iv, AES_DECRYPT);
            return 0;
        } else {
            return 1;
        }
    }
}

int getScryptEncryptedSize(unsigned int decryptedsize) {


return 1 + VK_SCRYPT_SALT_LEN + AES_BLOCK_SIZE + (((decryptedsize + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE);
}

int main(){
    uint8_t encrypted[getScryptEncryptedSize(320)];
    uint8_t decrypted[320];

    scryptencrypt("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",320,"password",8,encrypted);
    hex_print(encrypted,getScryptEncryptedSize(320));
    scryptdecrypt(encrypted,getScryptEncryptedSize(320),"password",8,decrypted);
    hex_print(decrypted,320);
}

0 个答案:

没有答案