设为首页 加入收藏

TOP

Java AES算法和UNIX下OpenSSL之间的加解密(一)
2015-02-02 14:21:49 来源: 作者: 【 】 浏览:20
Tags:Java AES 算法 UNIX OpenSSL 之间 解密

我先贴出源码:


aes.c:


?/**
? build with shell:
? gcc -Wall aes.c -lcrypto -o aes
**/
? ?
#include
#include
#include
#include
?
void encrypt(unsigned char* in, int inl, unsigned char *out, int* len, unsigned char * key){
? ? unsigned char iv[8];
? ? EVP_CIPHER_CTX ctx;
? ? //此init做的仅是将ctx内存 memset为0?
? ? EVP_CIPHER_CTX_init(&ctx);
?
? ? //cipher? = EVP_aes_128_ecb();?
? ? //原型为int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv)? ?
? ? //另外对于ecb电子密码本模式来说,各分组独立加解密,前后没有关系,也用不着iv?
? ? EVP_EncryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, key, iv);?
?
? ? *len = 0;
? ? int outl = 0;
? ? //这个EVP_EncryptUpdate的实现实际就是将in按照inl的长度去加密,实现会取得该cipher的块大小(对aes_128来说是16字节)并将block-size的整数倍去加密。
? ? //如果输入为50字节,则此处仅加密48字节,outl也为48字节。输入in中的最后两字节拷贝到ctx->buf缓存起来。?
? ? //对于inl为block_size整数倍的情形,且ctx->buf并没有以前遗留的数据时则直接加解密操作,省去很多后续工作。?
? ? EVP_EncryptUpdate(&ctx, out+*len, &outl, in+*len, inl);
? ? *len+=outl;
? ? //余下最后n字节。此处进行处理。
? ? //如果不支持pading,且还有数据的话就出错,否则,将block_size-待处理字节数个数个字节设置为此个数的值,如block_size=16,数据长度为4,则将后面的12字节设置为16-4=12,补齐为一个分组后加密?
? ? //对于前面为整分组时,如输入数据为16字节,最后再调用此Final时,不过是对16个0进行加密,此密文不用即可,也根本用不着调一下这Final。
? ? int test = inl>>4;
? ? if(inl != test<<4){
? ? ? ? EVP_EncryptFinal_ex(&ctx,out+*len,&outl);?
? ? ? ? *len+=outl;
? ? }
? ? EVP_CIPHER_CTX_cleanup(&ctx);
}
?
?
void decrypt(unsigned char* in, int inl, unsigned char *out, unsigned char *key){
? ? unsigned char iv[8];
? ? EVP_CIPHER_CTX ctx;
? ? //此init做的仅是将ctx内存 memset为0?
? ? EVP_CIPHER_CTX_init(&ctx);
?
? ? //cipher? = EVP_aes_128_ecb();?
? ? //原型为int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv)? ?
? ? //另外对于ecb电子密码本模式来说,各分组独立加解密,前后没有关系,也用不着iv?
? ? EVP_DecryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, key, iv);?
? ? int len = 0;
? ? int outl = 0;
?
? ? EVP_DecryptUpdate(&ctx, out+len, &outl, in+len, inl);
? ? len += outl;
? ? ? ?
? ? EVP_DecryptFinal_ex(&ctx, out+len, &outl);?
? ? len+=outl;
? ? out[len]=0;
? ? EVP_CIPHER_CTX_cleanup(&ctx);
}
int main(int argc, char **argv)
{
? ? unsigned char content[400];
? ? unsigned char key[] = "HelloWorld";
? ? ?
? ? unsigned char en[400],de[400],base64[400], base64_out[400];
? ? int len;?
? ? memset(content, 0,400);
? ? memset(en, 0, 400);
? ? memset(de, 0, 400);
? ? memset(base64, 0,400);
? ? memset(base64_out, 0, 400);
? ? strcpy(content, "HelloHbnfjkwahgruiep");
? ? ?
? ? printf("%d %s\n", strlen((const char*)content), content);
? ? encrypt(content,strlen((const char*)content), en, &len, key);
? ? ?
? ? int encode_str_size = EVP_EncodeBlock(base64, en, len);
? ? printf("%d %s\n", encode_str_size, base64);
? ? ?
? ? int length = EVP_DecodeBlock(base64_out, base64, strlen((const char*)base64));
? ? //EVP_DecodeBlock内部同样调用EVP_DecodeInit + EVP_DecodeUpdate + Evp_DecodeFinal实现,但是并未处理尾部的'='字符,因此结果字符串长度总是为3的倍数
? ? while(base64[--encode_str_size] == '=') length--;
? ? ?
? ? decrypt(base64_out, length, de, key);
? ? printf("%d %s\n", strlen((const char*)de), de);
? ? return 0;
}


makefile


CFLAGS=-g -c -Aa -Ae +DD64
APPLIBS=-L/opt/openssl/0.9.8/lib/hpux64 -lssl -lcrypto -L/usr/lib/hpux64
CC=cc
all: aes
.c.o:
? ? ? ? $(CC) $(CFLAGS) $*.c
aes:? aes.o
? ? ? ? $(CC) -o aes aes.o \
? ? ? ? ? ? ? ? $(APPLIBS) +DD64
clean:
? ? ? ? rm -f *.o


? ? aes.c源码我就不讲了,大家可以参照上面那个链接里面的,这里主要讲下makefile里面的注意点。
? ? makefile文件里如果没有-L/opt/openssl/0.9.8/lib/hpux64 -lssl -lcrypto则会抛出以下错误:


ld: Unsatis

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇如何编写Linux下的cat命令? 下一篇Java AES算法和OpenSSL配对

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: