Dict.CN 在线词典, 英语学习, 在线翻译

都市淘沙者

荔枝FM Everyone can be host

统计

留言簿(23)

积分与排名

优秀学习网站

友情连接

阅读排行榜

评论排行榜

关于AES(16字节)加密解密算法的java实现

关于AES(16字节)加密解密算法的java实现
根据指定的字符串来实现AES加密和解密,密匙可参数化配置,加密后数据的前两个字节是数据包的长度,加密算法选用AES
/ECB /PKCS5Padding。即采用标准AES算法,把全报文按照每块16字节分块进行加解密,对于不足16字节的数据块按照PKCS5方式补充,缺少N 个字节则把缺少的N个字节都以N来填充,最后一个数据块刚好16字节,则增加一个全部字节都填充为16的数据块。
=====================================
AesHandler.java
=====================================
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.List;

import javax.crypto.Cipher;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.SecretKeySpec;

import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.dom4j.DocumentException;
import org.dom4j.Element;

public class AesHandler {

private String plainTextFile = "src/encode.txt";// 明文文件
private String cipherTextFile = "src/aesDecode.txt";// 密文文件
private String keyFile = "src/aesKey.xml";// 加密密匙文件

/**
*
@param keyName
*            加密密匙名
@return
*/
public SecretKeySpec createKey(String keyName) {
SAXReader reader 
= new SAXReader();
Document doc;
SecretKeySpec skeySpec 
= null;
byte[] raw;
File keyXmlFile 
= new File(keyFile);
try {
doc 
= reader.read(keyXmlFile);
Element root 
= doc.getRootElement();
List items 
= root.elements("key16");
for(int i = 0; i < items.size(); i++){
Element node 
= (Element)items.get(i);
if(keyName.equalsIgnoreCase(node.attributeValue("name"))){
raw 
= node.attributeValue("value").getBytes("ASCII");
skeySpec 
= new SecretKeySpec(raw, "AES");
return skeySpec;
}
}
catch (DocumentException e) {
e.printStackTrace();
// throw new HiException(HiMessageCode.ERR_PARSE_FAILURE, _fmtFile,
// e);
catch (MalformedURLException e) {
e.printStackTrace();
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return skeySpec;
}

/**
*
@param code
*            选择加密或解密操作码
@param keyFileStr
*            加密密匙文件
@param plainFile 明文文件
@param cipherFile 密文文件
@param keyName 密匙名          
*/
public void run(String code, String keyName) {
int mode = Cipher.ENCRYPT_MODE;
InputStream in 
= null;
OutputStream out 
= null;
try {
SecretKeySpec skeySpec 
= createKey(keyName);
Cipher cipher 
= Cipher.getInstance("AES/ECB/PKCS5Padding");
if ("DECODE".equals(code)) {
mode 
= Cipher.DECRYPT_MODE;
in 
= new FileInputStream(cipherTextFile);
out 
= new FileOutputStream(plainTextFile);
cipher.init(mode, skeySpec);
decrypt(in, out, cipher);
// 解密
else {
in 
= new FileInputStream(plainTextFile);
out 
= new FileOutputStream(cipherTextFile);
cipher.init(mode, skeySpec);
encrypt(in, out, cipher);
// 加密
}
in.close();
out.close();
catch (Exception e) {
e.printStackTrace();
}
}

public static byte[] shortToByteArray(int valor) {
byte[] result = new byte[2];
for (int i = 0; i < result.length; i++) {
result[
1 - i] = (byte) (valor & 0xFF);
valor 
= valor >> 8;
}
return result;
}

/**
* 加密算法
*
@param in
*            明文数据流
@param out
*            密文数据流
@param cipher
@throws IOException
@throws ShortBufferException
@throws GeneralSecurityException
*/
public static void encrypt(InputStream in, OutputStream out, Cipher cipher)
throws IOException, ShortBufferException, GeneralSecurityException {
int blockSize = cipher.getBlockSize();
int outputSize = cipher.getOutputSize(blockSize);
byte[] inBytes = new byte[blockSize];
byte[] outBytes = new byte[outputSize];
byte[] appendAllBytes = new byte[blockSize];
byte[] appendBytes = new byte[blockSize];
int inLength = 0;
int length1 = in.available();
boolean more = true;
int yushu = length1 % 16;
if (yushu == 0) {
for (int i = 0; i < 16; i++) {
appendAllBytes[i] 
= new Integer(16).byteValue();
}
out.write(shortToByteArray(length1 
+ blockSize));
else {
int N = blockSize - yushu;
out.write(shortToByteArray(length1 
+ N));
}
while (more) {
inLength 
= in.read(inBytes);
if (inLength == blockSize) {
int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
out.write(outBytes, 
0, outLength);
else
more 
= false;
}
if (inLength > 0 && inLength < blockSize) {// 不足16字节的数据块按照PKCS5方式补充,缺少N个字节则把缺少的N个字节都以N来填充
int N = blockSize - inLength;
for (int M = inLength; M < blockSize; M++) {
inBytes[M] 
= new Integer(N).byteValue();
}
outBytes 
= cipher.doFinal(inBytes, 0, inLength);
out.write(outBytes);
else if (inLength == 0) {// 如果正好是16位,则增加一个全部字节都填充为16的数据块
int outLength = cipher.doFinal(appendBytes, 0, blockSize, outBytes);
out.write(outBytes, 
0, outLength);
}
out.flush();
}

/**
* 解密算法
*
@param in
*            密文数据流
@param out
*            明文数据流
@param cipher
@throws IOException
@throws ShortBufferException
@throws GeneralSecurityException
*/
public static void decrypt(InputStream in, OutputStream out, Cipher cipher)
throws IOException, ShortBufferException, GeneralSecurityException {
int blockSize = cipher.getBlockSize();
int outputSize = cipher.getOutputSize(blockSize);
byte[] inBytes = new byte[blockSize];
byte[] outBytes = new byte[outputSize];
byte[] dataLength = new byte[2];
int inLength = 0;
boolean more = true;
in.read(dataLength);
// 将数据包的长度读入到byte数组中
while (more) {
inLength 
= in.read(inBytes);
if (inLength == blockSize) {
int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
out.write(outBytes, 
0, outLength);
else
more 
= false;
}
if (inLength > 0) {
outBytes 
= cipher.doFinal(inBytes, 0, inLength);
else {
outBytes 
= cipher.doFinal();
}
out.write(outBytes);
out.flush();
}

public String getPlainTextFile() {
return plainTextFile;
}

public void setPlainTextFile(String plainTextFile) {
this.plainTextFile = plainTextFile;
}

public String getCipherTextFile() {
return cipherTextFile;
}

public void setCipherTextFile(String cipherTextFile) {
this.cipherTextFile = cipherTextFile;
}
public String getKeyFile() {
return keyFile;
}

public void setKeyFile(String keyFile) {
this.keyFile = keyFile;
}
}
=======================================================================
aesKey.xml文件
=============================
<?xml version="1.0" encoding="GB2312"?>
<KEY>
<key16 name="test" value="16BAESBocHK2Mcis"></key16>
</KEY>
=======================================================================
测试:
加密密钥: 16BAESBocHK2Mcis
明文: ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$
%!&*()_+-=:;'?,./
密文为:  
=========================From 001 Lines to 016============================
Debug: 
-1--2--3--4--5--6--7--8--9-HEX-1--2--3--4--5--6   ---ASCII Value--
0000100 40 0e 49 32 64 f8 07 c0 fd 22 80 49 6f 80 32   .@.I2d..例".Io.2
0000250 c5 97 73 f4 55 83 fb 59 6d 85 3c 82 1c 30 a3   P艞s.U凔Ym.<..0.
00003: d8 49 45 fc e2 83 3d 39 a2 d2 6e 06 4f a6 94 1c   .IE .=9⒁n.O .
0000419 2d 38 6d 81 e7 34 3b f7 5d 2b ff 83 a6 14 c2   .-8m佺4;.]+?..
00005: 2d 0e                                            >-.
====================================end================================

posted on 2011-03-16 18:11 都市淘沙者 阅读(4426) 评论(0)  编辑  收藏 所属分类: 加密解密/其他分类


只有注册用户登录后才能发表评论。


网站导航: