java與c互通aes加密解密

參考

https://blog.csdn.net/weiyuefei/article/details/72741729

 

SHA1PRNG與c語言的互通轉換,隨機數生成

https://blog.csdn.net/diliaolu1763/article/details/101628501

SHA1PRNG

    The name of the pseudo-random number generation (PRNG) algorithm supplied by the SUN provider. This algorithm uses SHA-1 as the foundation of the PRNG. It computes the SHA-1 hash over a true-random seed value concatenated with a 64-bit counter which is incremented by 1 for each operation. From the 160-bit SHA-1 output, only 64 bits are used.

 

 

java代碼

aes.java


//package com.syni.app.utils;

//import org.springframework.util.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * 描述:
 * AES加密解密工具
 *
     
 */
public class AESUtil {
    private static final String encodeKey = "123456789";
    private static final String ENCRYPTION_ALGORITHM = "AES";
	private static final String ENCRYPTION_ALGORITHM_ECB = "AES/ECB/PKCS5Padding";
	
    public static String AESEncode(String encodeRules, String content) {
        //無加密規則值時,使用默認值
        if (encodeRules == null || "".equals(encodeRules)) {
            encodeRules = encodeKey;
        }
        try {
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            random.setSeed(encodeRules.getBytes());
            //1.構造密鑰生成器,指定爲AES算法,不區分大小寫
            KeyGenerator keygen = KeyGenerator.getInstance(ENCRYPTION_ALGORITHM);
            //2.根據ecnodeRules規則初始化密鑰生成器
            //生成一個128位的隨機源,根據傳入的字節數組
            keygen.init(128, random);
            //3.產生原始對稱密鑰
            SecretKey original_key = keygen.generateKey();
            //4.獲得原始對稱密鑰的字節數組
            byte[] raw = original_key.getEncoded();
            
            System.out.println(raw.length);
            System.out.printf("real key:{");
            for(int i=0;i<raw.length;i++) {
				System.out.printf("0x%x", (byte)raw[i]);
				if(i < raw.length - 1) {
					System.out.printf(",");
				}
			}
			System.out.printf("}\n");
            //System.out.println(raw);
            //5.根據字節數組生成AES密鑰
            SecretKey key = new SecretKeySpec(raw, ENCRYPTION_ALGORITHM);
            
            //6.根據指定算法AES自成密碼器
            Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM_ECB);
            //7.初始化密碼器,第一個參數爲加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二個參數爲使用的KEY
            cipher.init(Cipher.ENCRYPT_MODE, key);
            //8.獲取加密內容的字節數組(這裏要設置爲utf-8)不然內容中如果有中文和英文混合中文就會解密爲亂碼
            byte[] byte_encode = content.getBytes("utf-8");
            //9.根據密碼器的初始化方式--加密:將數據加密
            byte[] byte_AES = cipher.doFinal(byte_encode);
            //10.將加密後的數據轉換爲字符串
            //這裏用Base64Encoder中會找不到包
            //解決辦法:
            //在項目的Build path中先移除JRE System Library,再添加庫JRE System Library,重新編譯後就一切正常了。
            //11.將字符串返回
            return new String(Base64.getEncoder().encode(byte_AES));
        } catch (Exception e) {
            return null;
        }
    }
     /* 解密
     * 解密過程:
     * 1.同加密1-4步
     * 2.將加密後的字符串反紡成byte[]數組
     * 3.將加密內容解密
     */
    public static String AESDncode(String encodeRules, String content) {
        //無加密規則值時,使用默認值
        if (encodeRules == null || "".equals(encodeRules)) {
            encodeRules = encodeKey;
        }
        try {
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            random.setSeed(encodeRules.getBytes());
            //1.構造密鑰生成器,指定爲AES算法,不區分大小寫
            KeyGenerator keygen = KeyGenerator.getInstance(ENCRYPTION_ALGORITHM);
            //2.根據ecnodeRules規則初始化密鑰生成器
            //生成一個128位的隨機源,根據傳入的字節數組
            keygen.init(128, random);
            //3.產生原始對稱密鑰
            SecretKey original_key = keygen.generateKey();
            //4.獲得原始對稱密鑰的字節數組
            byte[] raw = original_key.getEncoded();
            //5.根據字節數組生成AES密鑰
            SecretKey key = new SecretKeySpec(raw, ENCRYPTION_ALGORITHM);
            //6.根據指定算法AES自成密碼器
            Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM_ECB);
            //7.初始化密碼器,第一個參數爲加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二個參數爲使用的KEY
            cipher.init(Cipher.DECRYPT_MODE, key);
            //8.將加密並編碼後的內容解碼成字節數組
            byte[] byte_content = Base64.getDecoder().decode(content);
            /*
             * 解密
             */
            byte[] byte_decode = cipher.doFinal(byte_content);
            return new String(byte_decode, "utf-8");
        } catch (Exception e) {
            return null;
        }
    }
  
}

/*
class Hello {
	public static void main (String args[]){
		System.out.println("Hello Java,This is my first Java Application!");
	}
}

class person {
 
    public static void main(String[] args) {
        System.out.println("hello");
    }
 
}
*/


class person {
	public static void main(String[] args ) {
		AESUtil encode = new AESUtil();
		String url = "http://192.168.7.101/duilian/small.jpg";
		String s_e;
		String ba64;
		s_e = encode.AESEncode("123456789", url);	
		System.out.println(url);
		System.out.println(s_e);

		
		
		s_e = encode.AESDncode("123456789", s_e);
		System.out.println(s_e);
		
		//s_e = "123456";
		
		//s_e = new String(Base64.getEncoder().encode(s_e.getBytes()));
		//System.out.println(s_e);
		
	}
}

 

安裝java虛擬機

java版本

java -version
java version "9-ea"

 

編譯

javac aes.java

執行

java person

結果

java person
16
real key:{0xcc,0x67,0x4,0x3c,0x7b,0xcf,0xf5,0xee,0xa5,0x56,0x6b,0xd9,0xb1,0xf3,0xc7,0x4f}
http://192.168.7.101/duilian/small.jpg
FS40WNh8U+YJd9KKCmL2oJu8djSv9Rst8RWj3cbe0/LguNC+6IW3Ut47ck5NXcwl
http://192.168.7.101/duilian/small.jpg

 

c語言解密

main.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <string.h>
 
unsigned char *base64_encode(unsigned char *str)
{
    long len;
    long str_len;
    unsigned char *res;
    int i,j;
//定義base64編碼表
    unsigned char *base64_table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
//計算經過base64編碼後的字符串長度
    str_len=strlen(str);
    if(str_len % 3 == 0)
        len=str_len/3*4;
    else
        len=(str_len/3+1)*4;
 
    res=malloc(sizeof(unsigned char)*len+1);
    res[len]='\0';
 
//以3個8位字符爲一組進行編碼
    for(i=0,j=0;i<len-2;j+=3,i+=4)
    {
        res[i]=base64_table[str[j]>>2]; //取出第一個字符的前6位並找出對應的結果字符
        res[i+1]=base64_table[(str[j]&0x3)<<4 | (str[j+1]>>4)]; //將第一個字符的後位與第二個字符的前4位進行組合並找到對應的結果字符
        res[i+2]=base64_table[(str[j+1]&0xf)<<2 | (str[j+2]>>6)]; //將第二個字符的後4位與第三個字符的前2位組合並找出對應的結果字符
        res[i+3]=base64_table[str[j+2]&0x3f]; //取出第三個字符的後6位並找出結果字符
    }
 
    switch(str_len % 3)
    {
        case 1:
            res[i-2]='=';
            res[i-1]='=';
            break;
        case 2:
            res[i-1]='=';
            break;
    }
 
    return res;
}
 
unsigned char *base64_decode(unsigned char *code)
{
//根據base64表,以字符找到對應的十進制數據
    int table[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,62,0,0,0,63,52,53,54,55,56,57,58,59,60,61,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
    long len;
    long str_len;
    unsigned char *res;
    int i,j;
 
//計算解碼後的字符串長度
    len=strlen(code);
//判斷編碼後的字符串後是否有=
    if(strstr(code,"=="))
        str_len=len/4*3-2;
    else if(strstr(code,"="))
        str_len=len/4*3-1;
    else
        str_len=len/4;
 
    res=malloc(sizeof(unsigned char)*str_len+1);
    res[str_len]='\0';
 
//以4個字符爲一位進行解碼
    for(i=0,j=0;i < len-2;j+=3,i+=4)
    {
        res[j]=((unsigned char)table[code[i]])<<2 | (((unsigned char)table[code[i+1]])>>4); //取出第一個字符對應base64表的十進制數的前6位與第二個字符對應base64表的十進制數的後2位進行組合
        res[j+1]=(((unsigned char)table[code[i+1]])<<4) | (((unsigned char)table[code[i+2]])>>2); //取出第二個字符對應base64表的十進制數的後4位與第三個字符對應bas464表的十進制數的後4位進行組合
        res[j+2]=(((unsigned char)table[code[i+2]])<<6) | ((unsigned char)table[code[i+3]]); //取出第三個字符對應base64表的十進制數的後2位與第4個字符進行組合
    }
 
    return res;
 
}


#define	MAX_URL_SIZE	100

#define	ENCRYPT_MAX_SIZE	(MAX_URL_SIZE + AES_BLOCK_SIZE*6)

int main(void)
{
    char userkey[EVP_MAX_KEY_LENGTH] = {0xcc,0x67,0x4,0x3c,0x7b,0xcf,0xf5,0xee,0xa5,0x56,0x6b,0xd9,0xb1,0xf3,0xc7,0x4f};
    char iv[EVP_MAX_IV_LENGTH];
    unsigned char *date = malloc(MAX_URL_SIZE);
    unsigned char *encrypt = malloc(ENCRYPT_MAX_SIZE);
    unsigned char *plain;// = malloc(ENCRYPT_MAX_SIZE);
    EVP_CIPHER_CTX ctx;
    int ret;
    int tlen = 0;
    int mlen = 0;
    int flen = 0;
    unsigned char *p;
	int data_len = 0;


	unsigned char need_encrypt[1024] = "FS40WNh8U+YJd9KKCmL2oJu8djSv9Rst8RWj3cbe0/LguNC+6IW3Ut47ck5NXcwl";
	int need_encrypt_len;// = strlen(need_encrypt);

	
	memset(encrypt, 0, ENCRYPT_MAX_SIZE);
	strcpy(encrypt, "123456");
	//p = base64_encode(encrypt);
	//printf("<%s>\n", p);
	//p = base64_decode(p);
	//printf("<%s>\n", p);
	

    //memset((void*)userkey, 'k', EVP_MAX_KEY_LENGTH);
    memset((void*)iv, 'i', EVP_MAX_IV_LENGTH);
    //memset((void*)date, 'p', MAX_URL_SIZE);
	strcpy(date, "http://192.168.7.101/duilian/small.jpg");
    memset((void*)encrypt, 0, ENCRYPT_MAX_SIZE);
    

	data_len = strlen(date);
    /*初始化ctx*/
    EVP_CIPHER_CTX_init(&ctx);
	#if 0
    /*指定加密算法及key和iv(此處IV沒有用)*/
    ret = EVP_EncryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, userkey, iv);
    if(ret != 1) {
        printf("EVP_EncryptInit_ex failed\n");
        exit(-1);
    }
    
    /*禁用padding功能*/
    EVP_CIPHER_CTX_set_padding(&ctx, 0);
    /*進行加密操作*/
	mlen = 0;
    ret = EVP_EncryptUpdate(&ctx, encrypt, &mlen, date, data_len);
    if(ret != 1) {
        printf("EVP_EncryptUpdate failed\n");
        exit(-1);
    }
	#else
	ret = EVP_EncryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, userkey, NULL);
    if(ret != 1) {
        printf("EVP_EncryptInit_ex failed\n");
        exit(-1);
    }
	mlen = 0;
    ret = EVP_EncryptUpdate(&ctx, encrypt, &mlen, date, data_len);
    if(ret != 1) {
        printf("EVP_EncryptUpdate failed\n");
        exit(-1);
    }	
	#endif
	flen = 0;
    /*結束加密操作*/
    ret = EVP_EncryptFinal_ex(&ctx, encrypt+mlen, &flen);
    if(ret != 1) {
        printf("EVP_EncryptFinal_ex failed\n");
        exit(-1);
    }
	tlen = mlen + flen;
	printf("mlen:%d, flen:%d, encry len:%d\n", mlen, flen, tlen);
    

    EVP_CIPHER_CTX_cleanup(&ctx);

	
    tlen = 0;
    mlen = 0;
    flen = 0; 
/////////////////////////////////////////////decode/////////////////
	EVP_CIPHER_CTX_init(&ctx);

	#if 0
    ret = EVP_DecryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, userkey, iv);
    if(ret != 1) {
        printf("EVP_DecryptInit_ex failed\n");
        exit(-1);
    }
    
    EVP_CIPHER_CTX_set_padding(&ctx, 0);
    ret = EVP_DecryptUpdate(&ctx, plain, &mlen, encrypt, AES_BLOCK_SIZE*3);
    if(ret != 1) {
        printf("EVP_DecryptUpdate failed\n");
        exit(-1);
    }
	#else
    ret = EVP_DecryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, userkey, NULL);
    if(ret != 1) {
        printf("EVP_DecryptInit_ex failed\n");
        exit(-1);
    }
	data_len = strlen(encrypt);
	printf("encrypt len:%d\n", data_len);
    plain = malloc(data_len + AES_BLOCK_SIZE*6);
	memset((void*)plain, 0, data_len + AES_BLOCK_SIZE*6);
	if(plain == NULL) {
		printf("malloc fail here\n");
		exit(-1);
	}
	mlen = 0;
	
    ret = EVP_DecryptUpdate(&ctx, plain, &mlen, encrypt, data_len);
    if(ret != 1) {
        printf("EVP_DecryptUpdate failed\n");
        exit(-1);
    }

	
	#endif
	flen = 0;
	
    ret = EVP_DecryptFinal_ex(&ctx, plain+mlen, &flen);
    if(ret != 1) {
        printf("EVP_DecryptFinal_ex failed\n");
        exit(-1);
    }
	printf("mlen:%d, flen:%d\n", mlen, flen);
	data_len = mlen + flen;
	plain[data_len] = '\0';
    /*對比解密後與原數據是否一致*/
    if(!memcmp(plain, date, strlen(plain))) {
        printf("test success\n");    
    } else {
        printf("test failed %d:%d\n", strlen(date), strlen(plain));    
		printf("encode original:%s\n", date);
		printf("decode plain:%s\n", plain);
    }
	printf("<%s>\n", plain);

    printf("encrypt: \n");
    int i;
    for(i = 0; i < strlen(encrypt); i ++){
        printf("%.2x ", encrypt[i]);    
		//printf("%c", encrypt[i]);  
        if((i+1)%32 == 0){
            printf("\n");
        }
    }
	
    printf("\n");
	p = base64_encode(encrypt);
	printf("decode is <%s>\n", p);

	p = base64_decode(need_encrypt);
	need_encrypt_len = strlen(p);
	printf("de cry len:%d\n", need_encrypt_len);
    for(i = 0; i < need_encrypt_len; i ++){
        printf("%.2x ", p[i]);    
		//printf("%c", encrypt[i]);  
        if((i+1)%32 == 0){
            printf("\n");
        }
    }

    return 0;
}

gcc main.c -o main -lssl -lcrypto

 

結果

mlen:32, flen:16, encry len:48
encrypt len:48
mlen:32, flen:6
test success
<http://192.168.7.101/duilian/small.jpg>
encrypt:
15 2e 34 58 d8 7c 53 e6 09 77 d2 8a 0a 62 f6 a0 9b bc 76 34 af f5 1b 2d f1 15 a3 dd c6 de d3 f2
e0 b8 d0 be e8 85 b7 52 de 3b 72 4e 4d 5d cc 25
decode is <FS40WNh8U+YJd9KKCmL2oJu8djSv9Rst8RWj3cbe0/LguNC+6IW3Ut47ck5NXcwl>
de cry len:48
15 2e 34 58 d8 7c 53 e6 09 77 d2 8a 0a 62 f6 a0 9b bc 76 34 af f5 1b 2d f1 15 a3 dd c6 de d3 f2
e0 b8 d0 be e8 85 b7 52 de 3b 72 4e 4d 5d cc 25

 

 

 

sha1的key生成

sha1.c

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <openssl/sha.h>
  
 static const char hex_chars[] = "0123456789abcdef";
  
 void convert_hex(unsigned char *md, unsigned char *mdstr)
 {
     int i;
     int j = 0;
     unsigned int c;
  
     for (i = 0; i < 20; i++) {
	printf("0x%02x,", md[i]);

         c = (md[i] >> 4) & 0x0f;
         mdstr[j++] = hex_chars[c];
         mdstr[j++] = hex_chars[md[i] & 0x0f];
     }
	printf("\n");
     mdstr[40] = '\0';
 }
  
 int main(int argc, char **argv)
 {
     SHA_CTX shactx;
     int i;
     char data[100] = "123456789";
     char md[SHA_DIGEST_LENGTH] = {0};
     char mdstr[40] = {0};
 	char md2[SHA_DIGEST_LENGTH] = {0};
 	
     SHA1_Init(&shactx);
     SHA1_Update(&shactx, data, strlen(data));

     SHA1_Final(md, &shactx);
     convert_hex(md, mdstr);
     printf ("SHA_DIGEST_LENGTH:%d, Result of SHA1 : %s\n", SHA_DIGEST_LENGTH, mdstr);
     
     
     bzero(data, sizeof(data));
     bzero(mdstr, sizeof(mdstr));
     bzero(md2, sizeof(md2));
     memcpy(data, md, SHA_DIGEST_LENGTH);
     
     SHA1_Init(&shactx);
     SHA1_Update(&shactx, data, SHA_DIGEST_LENGTH);

     SHA1_Final(md2, &shactx);
     printf("{");
     for(i = 0; i < 16; i++) {
     	printf("0x%02x", (unsigned char)md2[i]);
     	if(i < 15) {
     		printf(",");
     	}	
     }
     printf("}\n");
     convert_hex(md2, mdstr);
     printf ("SHA_DIGEST_LENGTH:%d, Result of SHA1 : %s\n", SHA_DIGEST_LENGTH, mdstr);
     
     
     #if 0
     bzero(mdstr, sizeof(mdstr));
     
     for(i = 0; i < 16; i++) {
      	srand(md[i]);
      	printf("%c,", hex_chars[rand() % 16]);
 	 }
 	 printf("\n");
	#endif
     
     
     return 0;
 }

gcc sha1.c -o sha1 -lssl
zengzhihao@kamo:~/encry$ ./sha1
0xf7,0xc3,0xbc,0x1d,0x80,0x8e,0x04,0x73,0x2a,0xdf,0x67,0x99,0x65,0xcc,0xc3,0x4c,0xa7,0xae,0x34,0x41,
SHA_DIGEST_LENGTH:20, Result of SHA1 : f7c3bc1d808e04732adf679965ccc34ca7ae3441
{0xcc,0x67,0x04,0x3c,0x7b,0xcf,0xf5,0xee,0xa5,0x56,0x6b,0xd9,0xb1,0xf3,0xc7,0x4f}
0xcc,0x67,0x04,0x3c,0x7b,0xcf,0xf5,0xee,0xa5,0x56,0x6b,0xd9,0xb1,0xf3,0xc7,0x4f,0xd9,0xa5,0xcf,0x5d,
SHA_DIGEST_LENGTH:20, Result of SHA1 : cc67043c7bcff5eea5566bd9b1f3c74fd9a5cf5

 

通用

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/sha.h>
#include <unistd.h>
#include <openssl/evp.h>
#include <openssl/aes.h>

#define	MAX_ENCODE_KEY_SIZE		100

//cipher text size
#define	MAX_CIP_SIZE			1024

const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

char * base64_encode( const unsigned char * bindata, char * base64, int binlength)
{
    int i, j;
    unsigned char current;

    for ( i = 0, j = 0 ; i < binlength ; i += 3 )
    {
        current = (bindata[i] >> 2) ;
        current &= (unsigned char)0x3F;
        base64[j++] = base64char[(int)current];

        current = ( (unsigned char)(bindata[i] << 4 ) ) & ( (unsigned char)0x30 ) ;
        if ( i + 1 >= binlength )
        {
            base64[j++] = base64char[(int)current];
            base64[j++] = '=';
            base64[j++] = '=';
            break;
        }
        current |= ( (unsigned char)(bindata[i+1] >> 4) ) & ( (unsigned char) 0x0F );
        base64[j++] = base64char[(int)current];

        current = ( (unsigned char)(bindata[i+1] << 2) ) & ( (unsigned char)0x3C ) ;
        if ( i + 2 >= binlength )
        {
            base64[j++] = base64char[(int)current];
            base64[j++] = '=';
            break;
        }
        current |= ( (unsigned char)(bindata[i+2] >> 6) ) & ( (unsigned char) 0x03 );
        base64[j++] = base64char[(int)current];

        current = ( (unsigned char)bindata[i+2] ) & ( (unsigned char)0x3F ) ;
        base64[j++] = base64char[(int)current];
    }
    base64[j] = '\0';
    return base64;
}

int base64_decode( const char * base64, unsigned char * bindata)
{
    int i, j;
    unsigned char k;
    unsigned char temp[4];
    for ( i = 0, j = 0; base64[i] != '\0' ; i += 4 )
    {
        memset( temp, 0xFF, sizeof(temp) );
        for ( k = 0 ; k < 64 ; k ++ )
        {
            if ( base64char[k] == base64[i] )
                temp[0]= k;
        }
        for ( k = 0 ; k < 64 ; k ++ )
        {
            if ( base64char[k] == base64[i+1] )
                temp[1]= k;
        }
        for ( k = 0 ; k < 64 ; k ++ )
        {
            if ( base64char[k] == base64[i+2] )
                temp[2]= k;
        }
        for ( k = 0 ; k < 64 ; k ++ )
        {
            if ( base64char[k] == base64[i+3] )
                temp[3]= k;
        }

        bindata[j++] = ((unsigned char)(((unsigned char)(temp[0] << 2))&0xFC)) |
                ((unsigned char)((unsigned char)(temp[1]>>4)&0x03));
        if ( base64[i+2] == '=' )
            break;

        bindata[j++] = ((unsigned char)(((unsigned char)(temp[1] << 4))&0xF0)) |
                ((unsigned char)((unsigned char)(temp[2]>>2)&0x0F));
        if ( base64[i+3] == '=' )
            break;

        bindata[j++] = ((unsigned char)(((unsigned char)(temp[2] << 6))&0xF0)) |
                ((unsigned char)(temp[3]&0x3F));
    }
    return j;
}


void get_sha1_key(char *ori, unsigned char *userkey16) 
{
	SHA_CTX shactx;
	unsigned char  sha1[SHA_DIGEST_LENGTH] = {0};
	char data[MAX_ENCODE_KEY_SIZE] = {0};
	int i;

	

	bzero(data, sizeof(data));
	memcpy(data, ori, strlen(ori));
	bzero(sha1, sizeof(sha1));
	SHA1_Init(&shactx);
    SHA1_Update(&shactx, data, strlen(data));
	SHA1_Final(sha1, &shactx);

	bzero(data, sizeof(data));
	memcpy(data, sha1, sizeof(sha1));
	bzero(sha1, sizeof(sha1));
	SHA1_Init(&shactx);
    SHA1_Update(&shactx, data, strlen(data));
	SHA1_Final(sha1, &shactx);
	
	//printf("ori size and key:%d\n\n{%s}\n---------->\n", strlen(ori), ori);
	printf("key to 16 bytes\n");
	printf("{%s}\n", ori);
	printf("---------->\n");
	printf("{");
	for(i = 0; i < 16; i++) {
		userkey16[i] = (unsigned char)sha1[i];
		printf("0x%02x", userkey16[i]);
		if(i < 15) {
			printf(",");
		}
	}
	printf("}\n\n");
}






int decrypt_test(char *userkey, unsigned char *ciphertext)
{
	unsigned char result[MAX_CIP_SIZE] = {0};
	int ciphertext_len = 0;
	EVP_CIPHER_CTX ctx;
	int ret;
	int i;

	ciphertext_len = base64_decode((const char*)ciphertext, result);
	#if 0
	printf("len:%d\n", ciphertext_len);
	for(i = 0; i < ciphertext_len; i++) {
		printf("0x%x ", result[i]);
	}
	printf("\n");
	#endif

	EVP_CIPHER_CTX_init(&ctx);
	
    ret = EVP_DecryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, (const unsigned char *)userkey, NULL);
    if(ret != 1) {
        printf("EVP_DecryptInit_ex failed[%s][%d]\n", __FUNCTION__, __LINE__);
        return -1;
    }

	bzero(ciphertext, sizeof(ciphertext));
    int total_len = 0;
    int mlen = 0;
    int flen = 0;

    ret = EVP_DecryptUpdate(&ctx, ciphertext, &mlen, result, ciphertext_len);
    if(ret != 1) {
        printf("EVP_DecryptUpdate failed[%s][%d]\n", __FUNCTION__, __LINE__);
        return -1;
    }

    ret = EVP_DecryptFinal_ex(&ctx, ciphertext+mlen, &flen);
    if(ret != 1) {
        printf("EVP_DecryptFinal_ex failed[%s][%d]\n", __FUNCTION__, __LINE__);
        return -1;
    }
	total_len = mlen + flen;
	ciphertext[total_len] = '\0';
	//printf("total len:%d, mlen:%d, flen:%d\n", total_len, mlen, flen);
	//printf("result(%s)\n", ciphertext);
	return 0;
}


int encrypt_test(char *userkey, unsigned char *ori_text)
{
	unsigned char result[MAX_CIP_SIZE] = {0};
	int ori_text_len = 0;
	EVP_CIPHER_CTX ctx;
	int ret;
	int i;
    int tlen = 0;
    int mlen = 0;
    int flen = 0;
    
	//ciphertext_len = base64_decode((const char*)ciphertext, result);


	ori_text_len = strlen(ori_text);
	mlen = 0;
	flen = 0;
	
	EVP_CIPHER_CTX_init(&ctx);
	
	ret = EVP_EncryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, (const unsigned char *)userkey, NULL);
    if(ret != 1) {
        printf("EVP_EncryptInit_ex failed[%s][%d]\n", __FUNCTION__, __LINE__);
        return -1;
    }
	
    ret = EVP_EncryptUpdate(&ctx, result, &mlen, ori_text, ori_text_len);
    if(ret != 1) {
        printf("EVP_EncryptUpdate failed[%s][%d]\n", __FUNCTION__, __LINE__);
        return -1;
    }	
	
    /*結束加密操作*/
    ret = EVP_EncryptFinal_ex(&ctx, result+mlen, &flen);
    if(ret != 1) {
        printf("EVP_EncryptFinal_ex failed[%s][%d]\n", __FUNCTION__, __LINE__);
        exit(-1);
    }
	tlen = mlen + flen;
	//printf("mlen:%d, flen:%d, encrypt len:%d\n", mlen, flen, tlen);
    
    EVP_CIPHER_CTX_cleanup(&ctx);

	bzero(ori_text, MAX_CIP_SIZE);
	base64_encode(result, ori_text, tlen);

	return 0;
}


int main(int argc, char **argv)
{
	char key[MAX_ENCODE_KEY_SIZE] = "abcde";
	char encode_key[20] = {0};
	char real_cipher[MAX_CIP_SIZE] = "9Av98lYDk1KUD2NTQNJPsdb6pzKAEtORoDqvlej96vTTK7n2s+dzj/l+rvAQV6El";
	
	int flag = 0;
	
	if(argc != 4) {
		printf("use default args\n");	
	} else {
		if(strstr(argv[1], "en")) {
			flag = 1;	
			printf("try to encrypt text to cipher\n");	
		} else {
			flag = 2;	
			printf("try to decrypt cipher to text\n");	
		}
		bzero(key, sizeof(key));
		strcpy(key, argv[2]);
		
		bzero(real_cipher, sizeof(real_cipher));
		strcpy(real_cipher, argv[3]);
	}
	
	
	
	get_sha1_key(key, encode_key);
	
	
	if((flag == 0) || (flag == 2)) {
	
		printf("cipher text to code\n");
		printf("{%s}\n---------->\n", real_cipher);
		if(decrypt_test(encode_key, (unsigned char*)real_cipher) == 0) {
			printf("{%s}\n", real_cipher);
		} else {
			printf("decode fail\n");
		}
	}
	
	if((flag == 0) || (flag == 1)) {
		printf("\n####################text to ciphter###################\n");
		printf("{%s}\n---------->\n", real_cipher);
		if(encrypt_test(encode_key, (unsigned char*)real_cipher) == 0) {
			printf("{%s}\n", real_cipher);
		} else {
			printf("encode fail\n");
		}
	}
	
	
	
	return 0;
}

./e_d de key  cipher

./e_d en key text

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章