AES加密

来源:互联网 发布:域名注册实名认证 编辑:程序博客网 时间:2024/06/03 18:54

AES 算法

AES加密过程是在一个4×4的字节矩阵上运作,这个矩阵又称为“体(state)”,其初值就是一个明文区块(矩阵中一个元素大小就是明文区块中的一个Byte)。

(1) AddRoundKey—矩阵中的每一个字节都与该次回合密钥(round key)做XOR运算;每个子密钥由密钥生成方案产生。
(2) SubBytes—通过一个非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。
(3) ShiftRows—将矩阵中的每个横列进行循环式移位。
(4) MixColumns—为了充分混合矩阵中各个直行的操作。这个步骤使用线性转换来混合每内联的四个字节。最后一个加密循环中省略MixColumns步骤,而以另一个AddRoundKey替换。

更多介绍

Android 平台Java

1) 生成密码方块

KeyGenerator kgen = KeyGenerator.getInstance("AES");SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");sr.setSeed(key); //把密码设置到seed里面kgen.init(128, sr); //设置长度128SecretKey skey = kgen.generateKey();byte[] raw = skey.getEncoded();

2)加密

SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");Cipher cipher = Cipher.getInstance("AES");cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(    new byte[cipher.getBlockSize()]));byte[] encrypted = cipher.doFinal(input_string_bytes);

3)解密

SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");Cipher cipher = Cipher.getInstance("AES");cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(    new byte[cipher.getBlockSize()]));byte[] decrypted = cipher.doFinal(encrypted);

* 完整代码 *

import java.security.SecureRandom;import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;public class Secrets {    public static String encrypt(String seed, String cleartext)            throws Exception {        byte[] rawKey = getRawKey(seed.getBytes());        byte[] result = encrypt(rawKey, cleartext.getBytes());        return toHex(result);    }    public static String decrypt(String seed, String encrypted)            throws Exception {        byte[] rawKey = getRawKey(seed.getBytes());        byte[] enc = toByte(encrypted);        byte[] result = decrypt(rawKey, enc);        return new String(result);    }    private static byte[] getRawKey(byte[] seed) throws Exception {        KeyGenerator kgen = KeyGenerator.getInstance("AES");        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");        sr.setSeed(seed);        kgen.init(128, sr);        SecretKey skey = kgen.generateKey();        byte[] raw = skey.getEncoded();        return raw;    }    private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");        Cipher cipher = Cipher.getInstance("AES");        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(                new byte[cipher.getBlockSize()]));        byte[] encrypted = cipher.doFinal(clear);        return encrypted;    }    private static byte[] decrypt(byte[] raw, byte[] encrypted)            throws Exception {        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");        Cipher cipher = Cipher.getInstance("AES");        cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(                new byte[cipher.getBlockSize()]));        byte[] decrypted = cipher.doFinal(encrypted);        return decrypted;    }    private static String toHex(String txt) {        return toHex(txt.getBytes());    }    private static String fromHex(String hex) {        return new String(toByte(hex));    }    private static byte[] toByte(String hexString) {        int len = hexString.length() / 2;        byte[] result = new byte[len];        for (int i = 0; i < len; i++)            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),                    16).byteValue();        return result;    }    private static String toHex(byte[] buf) {        if (buf == null)            return "";        StringBuffer result = new StringBuffer(2 * buf.length);        for (int i = 0; i < buf.length; i++) {            appendHex(result, buf[i]);        }        return result.toString();    }    private final static String HEX = "0123456789ABCDEF";    private static void appendHex(StringBuffer sb, byte b) {        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));    }}

使用OpenSSL的libcrypto

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/aes.h>#include <openssl/rand.h>#include <string.h>static void hex_print(const void* pv, size_t len){    const unsigned char * p = (const unsigned char*)pv;    if (NULL == pv)        printf("NULL");    else    {        size_t i = 0;        for (; i<len;++i)            printf("%02X ", *p++);    }    printf("\n");}// main entrypointint main(int argc, char **argv){    //密钥设置    int keylength = 128;    unsigned char aes_key[keylength/8];    memset(aes_key, 0, keylength/8);    //输入    size_t inputslength = strlen(argv[1])+1;    unsigned char aes_input[inputslength];    memcpy(aes_input, argv[1], inputslength);    /* init vector */    unsigned char iv_enc[AES_BLOCK_SIZE], iv_dec[AES_BLOCK_SIZE];    RAND_bytes(iv_enc, AES_BLOCK_SIZE);    memcpy(iv_dec, iv_enc, AES_BLOCK_SIZE);    //Buffer 设置    const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;    unsigned char enc_out[encslength];    unsigned char dec_out[inputslength];    memset(enc_out, 0, sizeof(enc_out));    memset(dec_out, 0, sizeof(dec_out));    // 这里可以设置 aes-cbc-128 aes-cbc-192 aes-cbc-256    AES_KEY enc_key, dec_key;    AES_set_encrypt_key(aes_key, keylength, &enc_key);    AES_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv_enc, AES_ENCRYPT);    AES_set_decrypt_key(aes_key, keylength, &dec_key);    AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT);    printf("original:\t");    hex_print(aes_input, sizeof(aes_input));    printf("encrypt:\t");    hex_print(enc_out, sizeof(enc_out));    printf("decrypt:\t");    hex_print(dec_out, sizeof(dec_out));    return 0;}

编译:

gcc -o aes_test aes_test.c -lcrypto
0 0
原创粉丝点击