我已经尝试制作一个程序,它将通过AES加密来加密字符串。在查看了stackoverflow和许多其他论坛后,我最终得到了这个。但是代码存在一些问题:
1.有时加密有时不起作用(20次尝试,2次失败)。怎么解决?它与ivec或textLength有关吗?
2.加密和解密后,我的主要人物只有16个第一个字符 字符串。之后我有一些随机字符。可以解密我的所有字符串,或者我必须剪切到16个字符?
3.我需要融合一些字符,所以我做了这个:
char ivec[16];
for(int i=0;i<16;i++)
{
ivec[i]=iveccreate[i];
}
但毕竟char ivec [16]有55个字符。知道为什么吗?
4.在功能AES_cbc_encrypt后,我的ivec改为一些完全不同的char。有没有办法阻止这个(我想减少代码的大小)?
我将非常感谢1-4个问题的答案。
MKAROL
PS:我来自波兰所以我的英语不太好。遗憾。有价值的代码:
#include <string.h>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <openssl/aes.h>
#include <time.h>
#include <stdlib.h>
#include <vector>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/rand.h>
using namespace std;
string AESencode(string Text,string Key);
void AESdecode(string in,string Key);
char *encode(unsigned char *input, int length);
char *decode(unsigned char *input,int lenght);
void main
{
string out=AESencode("String,which I want to encrypt.\0","encryptionkey");
AESdecode(out,"encryptionkey");
return 0;
}
string AESencode(string Text,string Key)
{
//Creating 16 random ive
srand((unsigned int) time(NULL));
unsigned char ive[16];
for(int i=0; i<16; i++){
ive[i] = (unsigned char) rand();
}
//I'm losing null by encode ive
char *iveccreate=encode(ive,16);
//Copying 16 first chars from iveccreate(16 random letters,numbers)
char ivec[16];
for(int i=0;i<16;i++)
{
ivec[i]=iveccreate[i];
}
//Saving ivec,because I need to fuse ivec with output later
//and after encode I lose orginal ivec
char* ivec1=decode((unsigned char*)iveccreate,strlen((const char*)iveccreate));
// Round up to AES_BLOCK_SIZE
size_t textLength = ((Text.length() / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
//If necessary adding null to the Key(full 32 bytes)
if(Klucz.length() < 32){
Key.append(32 - Key.length(), '\0');
}
//Creating space for the output
unsigned char *aesoutput = new unsigned char[textLength];
//Create and set AESkey
AES_KEY *aesKey = new AES_KEY;
AES_set_encrypt_key((unsigned char*)Key.c_str(), 256, aesKey);
//Encrypting
AES_cbc_encrypt((unsigned char*)Text.c_str(), aesoutput, Text.length()+ 1, aesKey, (unsigned char*)ivec, AES_ENCRYPT);
//Fusing ivec with aesoutput
char wyjsciowy[strlen((const char*)Wyjscie)+16];
for(int i=0;i<16;i++){
fuse[i]=ivec1[i];
}
for(int i=0;i<strlen((const char*)Wyjscie);i++) {
fuse[i+16]=aesouput[i];
}
//Encode the fuse
char* out=encode((unsigned char*)wyjsciowy,strlen(wyjsciowy));
//Saving chars to string
string mychar((char*)out);
//Creating normal string from the base64 encode output
//String is 65 chars, new line, 65 chars
//so I'm looking for the number of not 65, ending chars of the string
int res=mychar.length()%65;
string allstr;
//Fuse strings without new line charater
for(int i=0;i<(mychar.length()-res);i+=65)
{
allstr+=mychar.substr(i,64);
}
//Fuse string with the ending string.If res==0 it will add nothing.
allstr+=mychar.substr((mychar.length()-res),res);
//Returnig string
return allstr;
}
//Base64 encode function
char *encode(unsigned char *input, int length)
{
BIO *bmem, *b64;
BUF_MEM *bptr;
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, input, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
char *buff = (char *)malloc(bptr->length+1);
memcpy(buff, bptr->data, bptr->length);
buff[bptr->length] = 0;
BIO_free_all(b64);
return buff;
}
//Base64 decode function
char *decode(unsigned char *input, int length)
{
BIO *b64, *bmem;
char *buffer = (char *)malloc(length);
memset(buffer, 0, length);
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_new_mem_buf(input, length);
bmem = BIO_push(b64, bmem);
BIO_read(bmem, buffer, length);
BIO_free_all(bmem);
return buffer;
}
void AESdecode(string in,string Key)
{
//Decode the input string with Base64
char* dec=decode((unsigned char*)in.c_str(),in.length());
//Getting ivec
unsigned char ivec[16];
{
//Getting first 16 bytes from dec
unsigned char preivec[16];
for(int i=0;i<16; i++){
preivec[i] = dec[i];
}
//Encode these 16 bytes
char *ppiv=encode(preivec,16);
//Now we have 25 chars text
//And ivec is only fist 16
for(int i=0;i<25; i++){
ivec[i] = ppiv[i];
}
}
//Getting aesouput bytes
char data[strlen(dec)-16];
for(int i=16;i<(strlen(dec));i++){
data[i-16]=dec[i];
}
//If necessary adding null to the Key(full 32 bytes)
if(Key.length()< 32){
Key.append(32-Key.length(),'\0');
}
//Creating space for the output
unsigned char *output = new unsigned char[strlen(data)];
//Create and set new AESkey
AES_KEY *aesKey = new AES_KEY;
AES_set_decrypt_key((unsigned char*)Key.c_str(), 256, aesKey);
// key length is in bits, so 32 * 8 = 256
//Deccrypting
AES_cbc_encrypt((unsigned char*)data, output, strlen(data), aesKey,ivec, AES_DECRYPT);
//And there should be full primary string
cout<<"OUTPUT: "<<output<<endl;
}
答案 0 :(得分:0)
AES密钥是固定长度的字节数组,而不是可变长度字符串。当你调用AES_set_decrypt_key()时,你给它一个13个字符长的字符串,添加一个空字节,所以我们知道14个字节。然后该功能将使用(32-14) - &gt;其密钥的剩余18个字节。这18个字节的内容主要是幸运的结果
我怀疑这是你的问题。