1.加密的基本原理
加密分为对称加密和非对称加密,对称加密就是加密方和解密放用同一个密钥。
加密是分组加密,即将明文数据分成多个密钥大小的块,依次和密钥运算,输出密文。
padding,由于加密需要分组,就要保证最后一组数据大小和密钥一样大,补齐方式有多种,常见的是缺几补几。
推荐博客:
https://www.cnblogs.com/adylee/archive/2007/09/14/893438.html
2.常用库
openssl 下 aes.h
/* crypto/aes/aes.h */
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
*/
#ifndef HEADER_AES_H
/*
* Because array size can't be a const in C, the following two are macros.
* Both sizes are in bytes.
*/
#ifdef __cplusplus
extern "C" {
#endif
/* This should be a hidden type, but EVP requires that the size be known */
struct aes_key_st {
unsigned long rd\_key\[4 \* (AES\_MAXNR + 1)\];
unsigned int rd\_key\[4 \* (AES\_MAXNR + 1)\];
int rounds;
};
typedef struct aes_key_st AES_KEY;
const char *AES_options(void);
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
void AES_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void AES_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, const int enc);
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num, const int enc);
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);
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);
void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num);
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);
/* NB: the IV is _two_ blocks long */
void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
/* NB: the IV is _four_ blocks long */
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);
int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
unsigned char *out,
const unsigned char *in, unsigned int inlen);
int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
unsigned char *out,
const unsigned char *in, unsigned int inlen);
#ifdef __cplusplus
}
#endif
#endif /* !HEADER_AES_H */
3.使用
(1)下面以 aes-128-ecb 并使用base64的实现,aes表示对称加密,ceb是一种加密模式,128表示128bit即16Bytes的密钥长度,base64是一种编码方式,将不可见字符转为可见字符,详见百度百科。
#ifndef _AES_128_ECB_H_
#define _AES_128_ECB_H_
int base64_encode(char *in_str, int in_len, char *out_str);
int base64_decode(char *in_str, int in_len, char *out_str);
int aes_128_ecb_encode(char *in, int in_len, char *out, int *out_len, const unsigned char *key);
int aes_128_ecb_decode(char *in, int in_len, char *out, int *out_len, const unsigned char *key);
#endif
#include
#include
#include
#include
#include
#include
#include
#include "openssl/pem.h"
#include "openssl/bio.h"
#include "openssl/evp.h"
#include "openssl/aes.h"
#include
#include
#define BUF_SIZE 1024
int base64_encode(char *in_str, int in_len, char *out_str);
int base64_decode(char *in_str, int in_len, char *out_str);
int aes_128_ecb_encode(char *in, int in_len, char *out, int *out_len, const unsigned char *key);
int aes_128_ecb_decode(char *in, int in_len, char *out, int *out_len, const unsigned char *key);
int main()
{
//AES_KEY aes;
struct aes_key_st enc_aes, dec_aes;
const unsigned char *in, *key = (unsigned char *)"f29848221a51a2bb";
unsigned char *out, buf2[BUF_SIZE] = {0};
int i, len, out_len;
int pading_begin, pading_end, pading;
struct stat st;
int fd;
char \*buf;
stat("./tmp", &st);
printf("size : %d\\n", st.st\_size);
buf= (char \*)malloc(st.st\_size\*2);
fd = open("./tmp", O\_RDONLY);
int nbytes = read(fd, buf, st.st\_size);
printf("buf : \\n%s\\n", buf);
//printf("nbytes : %d\\n", nbytes);
//printf("st\_size : %d\\n", st.st\_size);
// strncpy((char *)buf, "192.168.3.10", 1024);
// out_len = sizeof(buf);
out_len = st.st_size;
int len2 = strlen(buf);
//aes_128_ecb_encode(buf, strlen(buf), buf, &out_len, key);
// out_len = base64_encode(buf, out_len, buf);
// printf("base64_encode : \n%s\n", buf);
out_len = base64_decode(buf, out_len, buf);
aes_128_ecb_decode(buf, out_len, buf, &out_len, key);
printf("decode : \n%s\n", buf);
printf("len = %d\\n", st.st\_size);
printf("len2 = %d\\n", len2);
#if 0
printf("%s\n", AES_options());
if (AES_set_encrypt_key(key, 128, &enc_aes) < 0) {
printf("failed to set enc key");
exit(-1);
}
strncpy((char *)buf, "192.168.3.10", 1024);
in = buf;
out = buf;
printf("before encrypt : \n%s\n", buf);
/*-----------------------------pading begin-----------------------------*/
len = strlen((const char *)buf);
i = len/AES_BLOCK_SIZE + 1;
pading_end = i*AES_BLOCK_SIZE;
pading_begin = len;
printf("len = %d\n, i*AES_BLOCK_SIZE = %d\n", len, (i+1)*AES_BLOCK_SIZE);
pading = pading_end - pading_begin;
printf("pading : %d\n", pading);
memset((void *)(in + pading_begin), pading, pading);
len = i*AES_BLOCK_SIZE;
/*-----------------------------pading end-----------------------------*/
printf("after pading : \n%s\n", buf);
/\*-----------------------------encode begin-----------------------------\*/
for (i = 0; (i+1)\*AES\_BLOCK\_SIZE <= len; i++) {
AES\_ecb\_encrypt(in+i\*AES\_BLOCK\_SIZE, out+i\*AES\_BLOCK\_SIZE, &enc\_aes, AES\_ENCRYPT);
}
/\*-----------------------------encode end-----------------------------\*/
printf("after encrypt : \\n%s\\n", buf);
/\*-----------------------------base64 encode begin-----------------------------\*/
base64\_encode(buf, len, buf);
printf("after base64 encode : \\n%s\\n", buf);
/\*-----------------------------base64 encode end-----------------------------\*/
/\*-----------------------------base64 decode begin-----------------------------\*/
base64\_decode(buf, strlen(buf), buf);
printf("after base64 decode : \\n%s\\n", buf);
/\*-----------------------------base64 decode end-----------------------------\*/
if (AES\_set\_decrypt\_key(key, 128, &dec\_aes) < 0) {
printf("failed to set dec key");
exit(-1);
}
printf("before decrypt : \\n%s\\n", buf);
for (i = 0; (i+1)\*AES\_BLOCK\_SIZE <= len; i++) {
AES\_ecb\_encrypt(in+i\*AES\_BLOCK\_SIZE, out+i\*AES\_BLOCK\_SIZE, &dec\_aes, AES\_DECRYPT);
}
pading = in\[len-1\];
\*(char \*)(in + len - pading) = '\\0';
printf("after decrypt : \\n%s\\n", buf);
#endif
return 0;
}
int base64_encode(char *in_str, int in_len, char *out_str)
{
BIO *b64, *bio;
BUF_MEM *bptr = NULL;
size_t size = 0;
if (in\_str == NULL || out\_str == NULL)
return -1;
b64 = BIO\_new(BIO\_f\_base64());
bio = BIO\_new(BIO\_s\_mem());
bio = BIO\_push(b64, bio);
BIO\_write(bio, in\_str, in\_len);
BIO\_flush(bio);
BIO\_get\_mem\_ptr(bio, &bptr);
memcpy(out\_str, bptr->data, bptr->length);
out\_str\[bptr->length\] = '\\0';
size = bptr->length;
BIO\_free\_all(bio);
return size;
}
int base64_decode(char *in_str, int in_len, char *out_str)
{
BIO *b64, *bio;
BUF_MEM *bptr = NULL;
int counts;
int size = 0;
if (in\_str == NULL || out\_str == NULL)
return -1;
b64 = BIO\_new(BIO\_f\_base64());
BIO\_set\_flags(b64, BIO\_FLAGS\_BASE64\_NO\_NL);
bio = BIO\_new\_mem\_buf(in\_str, in\_len);
bio = BIO\_push(b64, bio);
size = BIO\_read(bio, out\_str, in\_len);
out\_str\[size\] = '\\0';
BIO\_free\_all(bio);
return size;
}
int aes_128_ecb_encode(char *in, int in_len, char *out, int *out_len, const unsigned char *key)
{
/*-----------------------------pading begin-----------------------------*/
int i, pading_end, pading_begin, ret = 0, pading;
struct aes_key_st enc_aes;
if (in_len > *out_len) {
printf("aes_128_ecb_encode err : in_len > out_len\n");
ret = -1;
goto __end__;
}
if (AES_set_encrypt_key(key, 128, &enc_aes) < 0) {
printf("failed to set enc key");
ret = -1;
goto __end__;
}
memcpy(out, in, in_len);
i = in_len/AES_BLOCK_SIZE + 1;
pading_end = i*AES_BLOCK_SIZE;
pading_begin = in_len;
pading = pading_end - pading_begin;
memset((void *)(out + pading_begin), pading, pading);
*out_len = i*AES_BLOCK_SIZE;
/*-----------------------------pading end-----------------------------*/
/*-----------------------------encode begin-----------------------------*/
for (i = 0; (i+1)*AES_BLOCK_SIZE <= *out_len; i++) {
AES_ecb_encrypt(out+i*AES_BLOCK_SIZE, out+i*AES_BLOCK_SIZE, &enc_aes, AES_ENCRYPT);
}
/*-----------------------------encode end-----------------------------*/
__end__:
return ret;
}
int aes_128_ecb_decode(char *in, int in_len, char *out, int *out_len, const unsigned char *key)
{
int i = 0, pading, ret = 0;
struct aes_key_st dec_aes;
if (in\_len == 0) {
goto \_\_end\_\_;
}
if (in\_len > \*out\_len) {
printf("aes\_128\_ecb\_decode err : in\_len > out\_len\\n");
ret = -1;
goto \_\_end\_\_;
}
if (AES\_set\_decrypt\_key(key, 128, &dec\_aes) < 0) {
printf("failed to set dec key");
ret = -1;
goto \_\_end\_\_;
}
memcpy(out, in, in\_len);
\*out\_len = in\_len;
for (i = 0; (i+1)\*AES\_BLOCK\_SIZE <= \*out\_len; i++) {
AES\_ecb\_encrypt(out+i\*AES\_BLOCK\_SIZE, out+i\*AES\_BLOCK\_SIZE, &dec\_aes, AES\_DECRYPT);
}
pading = out\[\*out\_len-1\];
\*(char \*)(out + \*out\_len - pading) = '\\0';
__end__:
return ret;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章