我总是丢失最后一部分,这里是我的代码,即使它使用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);
}