AES加密
2016-09-27 14:33
155 查看
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); //设置长度128 SecretKey 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.Ciphe
4000
r;
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 entrypoint int 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
相关文章推荐
- Redis学习之关闭持久化
- RNN,LSTM 反向传播算法的思考 & RNN,LSTM可以模块化的分析
- Redis学习之关闭持久化
- spring security 1
- mysql主主互备模式配置
- python列表分组的技巧
- MySQL 数据库及表的创建
- js闭包的用途
- Linux 命令(文件和目录管理 - pwd)
- Android系统进程Zygote启动过程的源代码分析
- Android 开源项目源码解析 -->HoloGraphLibrary 源码解析(九)
- CSS样式控制超长文本在div,p等块级容器中的自动换行
- Redis
- redis--sorted sets类型及操作
- CListCtrl自动滚动
- c# 并行运算
- C语言之多种方法交换两个变量的值
- 数据库无法创建数据库视图
- mac整站下载工具wget
- visual studio 2013 快捷键大全、VS2013常用快捷键