OpenSSL提供了AES加解密算法的API
const char *AES_options(void);
AES算法狀態,是全部支持或者是部分支持。
返回值:“aes(full)” 或者"aes(partial)"
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key);
設定加密用的Key;
userKey: 密鑰數值;
bits:密鑰長度,以bit爲單位,如果密鑰數字是16個字節,則此參數值應爲128;
key: AES_KEY對象指針;
返回值: 0 成功, -1 userkey,key爲空, -2: 密鑰長度不是128,192,256;
int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
設定解密用的Key;
userKey: 密鑰數值;
bits:密鑰長度,以bit爲單位,如果密鑰數字是16個字節,則此參數值應爲128;
key: AES_KEY對象指針;
返回值: 0 成功, -1 userkey,key爲空, -2: 密鑰長度不是128,192,256;
void AES_encrypt(const unsigned char *in, unsigned char *out,const AES_KEY *key);
AES 加密,加密單個數據塊,in,out可以是同一內存區;
in: 需要加密的數據;
out: 加密後的數據;
key:AES 密鑰;
void AES_decrypt(const unsigned char *in, unsigned char *out,const AES_KEY *key);
AES 解密,解密單個數據塊,in,out可以是同一內存區;
in: 需要解密的數據;
out: 解密後的數據;
key:AES 密鑰;
void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key, const int enc);
AES加密/解密單個數據塊,ECB模式
in: 需要加密/解密的數據;
out: 計算後輸出的數據;
key:密鑰
enc: AES_ENCRYPT 代表加密, AES_DECRYPT代表解密;
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, const int enc);
AES加密/解密單個數據塊,CBC模式
in: 需要加密/解密的數據;
out: 計算後輸出的數據;
length: 數據長度
key:密鑰
ivec: 初始向量
enc: AES_ENCRYPT 代表加密, AES_DECRYPT代表解密;
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num, const int enc);
AES CFB128位模式加密/解密,輸入輸出數據區可以重疊;
in: 需要加密/解密的數據;
out: 計算後輸出的數據;
length: 數據長度;
key: 密鑰;
ivec: 初始化向量
num: 輸出參數,計算狀態,多少個CFB數據塊
enc: 計算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT
void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num, const int enc);
AES CFB1位模式加密/解密,輸入輸出數據區可以重疊;
in: 需要加密/解密的數據;
out: 計算後輸出的數據;
length: 數據長度;
key: 密鑰;
ivec: 初始化向量
num: 輸出參數,計算狀態,多少個CFB數據塊
enc: 計算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT
void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num, const int enc);
AES CFB8位模式加密/解密,輸入輸出數據區可以重疊;
in: 需要加密/解密的數據;
out: 計算後輸出的數據;
length: 數據長度;
key: 密鑰;
ivec: 初始化向量
num: 輸出參數,計算狀態,多少個CFB數據塊
enc: 計算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT
void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num);
AES OFB128位模式加密/解密,輸入輸出數據區可以重疊;
in: 需要加密/解密的數據;
out: 計算後輸出的數據;
length: 數據長度;
key: 密鑰;
ivec: 初始化向量
num: 輸出參數,計算狀態,多少個CFB數據塊
enc: 計算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT
void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char ivec[AES_BLOCK_SIZE],
unsigned char ecount_buf[AES_BLOCK_SIZE],
unsigned int *num);
AES CTR128位模式加密/解密,輸入輸出數據區可以重疊;
in: 需要加密/解密的數據;
out: 計算後輸出的數據;
length: 數據長度;
key: 密鑰;
ivec: 初始化向量
ecount_buf: 輸出參加,加密的次數,在第一次調用此函數時,需要初始化爲0
num: 輸出參數,計算狀態,多少個CFB數據塊,在第一次調用此函數時,需要初始化爲0
enc: 計算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT
void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
AES 加密/解密,輸入輸出數據區可以重疊,初始化向量是加密數據塊的2倍,加密前用前半部分做一次異或,加密後用後半部分做一次異或;
in: 需要加密/解密的數據;
out: 計算後輸出的數據;
length: 數據長度;
key: 密鑰;
ivec: 初始化向量
enc: 計算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT
void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
const AES_KEY *key2, const unsigned char *ivec,
const int enc);
AES 加密/解密,輸入輸出數據區可以重疊,初始化向量是加密數據塊的4倍,加密前用第一部分做一次異或,加密後用第二部分做一次異或;
最後一個加密數據塊,加密前用第三部分異或,加密後用第四部分異或;
in: 需要加密/解密的數據;
out: 計算後輸出的數據;
length: 數據長度;
key: 密鑰;
ivec: 初始化向量
enc: 計算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT
int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
unsigned char *out,
const unsigned char *in, unsigned int inlen)
用AES算法對明文key數據加密
key: AES Key,用於加密密鑰數據
iv: 初始化向量
out: 加密後的密鑰數據
in: 密鑰數據
inlen: 密鑰數據長度
返回值: 1: 成功, 0: 失敗
int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
unsigned char *out,
const unsigned char *in, unsigned int inlen)
用AES算法對明文key數據加密
key: AES Key,用於加密密鑰數據
iv: 初始化向量
out: 加密後的密鑰數據
in: 密鑰數據
inlen: 密鑰數據長度
返回值: 1: 成功, 0: 失敗
C實例分析:
首先要了解AES加密是什麼,以及幾種加密模式的區別。之後纔是編程。具體的編程案例,在下面的鏈接。
openssl之aes加密(AES_cbc_encrypt 與 AES_encrypt 的編程案例)
- int aes_encrypt(char* in, char* key, char* out)//, int olen)
- {
- if(!in || !key || !out) return 0;
- AES_KEY aes;
- if(AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
- {
- return 0;
- }
- int len=strlen(in), en_len=0;
- while(en_len<len)//輸入輸出字符串夠長,並且是AES_BLOCK_SIZE的整數倍,需要嚴格限制
- {
- AES_encrypt((unsigned char*)in, (unsigned char*)out, &aes);
- in+=AES_BLOCK_SIZE;
- out+=AES_BLOCK_SIZE;
- en_len+=AES_BLOCK_SIZE;
- }
- return 1;
- }
- int aes_decrypt(char* in, char* key, char* out)
- {
- if(!in || !key || !out) return 0;
- AES_KEY aes;
- if(AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0)
- {
- return 0;
- }
- int len=strlen(in), en_len=0;
- while(en_len<len)
- {
- AES_decrypt((unsigned char*)in, (unsigned char*)out, &aes);
- in+=AES_BLOCK_SIZE;
- out+=AES_BLOCK_SIZE;
- en_len+=AES_BLOCK_SIZE;
- }
- return 1;
- }
分組對稱加密模式:ECB/CBC/CFB/OFB缺CTR
# cd /tmp
# echo "test測試" > test.txt
--開始加密, 使用aes-128-cbc算法, 也可以使用其他算法, 通過查看openssl的幫助可獲知
# openssl aes-128-cbc -salt -in test.txt -out test.txt.aes
enter aes-128-cbc encryption password:<輸入密碼>
Verifying - enter aes-128-cbc encryption password:<確認密碼>
--查看加密前後的文件大小, 加密後文件明顯增大了
# ll test.txt*
-rw-r--r-- 1 root root 9 Aug 11 15:42 test.txt
-rw-r--r-- 1 root root 32 Aug 11 15:43 test.txt.aes
--查看加密前後的文件內容, 加密後文件無法直接查看, 顯示亂碼
# cat test.txt
test測試
# cat test.txt.aes
Salted__碾RTqm6棚顱
--現在開始解密, 會提示輸入密碼, 如果密碼有誤則無法解密
# openssl aes-128-cbc -d -salt -in test.txt.aes -out test.txt.out
enter aes-128-cbc decryption password:<輸入錯誤密碼>
bad decrypt
6150:error:06065064:digital envelope routines:EVP_DecryptFinal:bad decrypt:evp_enc.c:438:
# openssl aes-128-cbc -d -salt -in test.txt.aes -out test.txt.out
enter aes-128-cbc decryption password:<輸入正確密碼>
--查看解密前後的文件大小, 和加密前是一樣的
# ll test.txt*
-rw-r--r-- 1 root root 9 Aug 11 15:42 test.txt
-rw-r--r-- 1 root root 32 Aug 11 15:43 test.txt.aes
-rw-r--r-- 1 root root 9 Aug 11 15:45 test.txt.out
--查看解密前後的文件內容, 和加密前是一樣的
# cat test.txt.out
test測試
這種方法非常適合Linux下的文件內容保密, 呵呵....以上命令加參數比較複雜, 我們可以把命令加參數做個函數, 然後放到.bash_profile裏, 這樣每次登陸後直接使用函數即可, 如下:
function jiami()
{
/usr/bin/openssl aes-128-cbc -salt -in $1 -out $1.aes && rm -f $1
}
function jiemi()
{
/usr/bin/openssl aes-128-cbc -d -salt -in $1.aes -out $1 && rm -f $1.aes
}
然後就可以如下使用了(注意輸入參數都是原文件名, 且會自動刪除原文件):
# jiami test.txt
enter aes-128-cbc encryption password:
Verifying - enter aes-128-cbc encryption password:
# jiemi test.txt
enter aes-128-cbc decryption password:
# ll test.txt*
-rw-r--r-- 1 root root 9 Aug 11 15:46 test.txt
-rw-r--r-- 1 root root 9 Aug 11 15:45 test.txt.out
--End--