基于java类库的对称加密算法实现

来源:互联网 发布:ubuntu 12.04 qq2013 编辑:程序博客网 时间:2024/06/07 09:45

        最近对java实现对称加密算法产生兴趣,研究了网上的一些资料,通过亲自上机实践,写了基于java类库的对称加密算法实现代码,完整代码如下:

import java.security.*;import javax.crypto.*;import javax.crypto.spec.*;public class Encryptor {public static final String ALGORITHM_DES = "DES";public static final String ALGORITHM_THREEDES = "DESede";public static final String ALGORITHM_AES = "AES";public static final String ALGORITHM_BLOWFISH = "Blowfish";private String algorithm;private Key key;private int blocksize;/** * 解密 */public byte[] decrypt(byte[] ivAndCiphertext) throws InvalidKeyException,NoSuchAlgorithmException, NoSuchPaddingException,InvalidAlgorithmParameterException, IllegalBlockSizeException,BadPaddingException {byte[] iv = new byte[this.blocksize];byte[] c = new byte[ivAndCiphertext.length - this.blocksize];System.arraycopy(ivAndCiphertext, 0, iv, 0, this.blocksize);System.arraycopy(ivAndCiphertext, this.blocksize, c, 0,ivAndCiphertext.length - this.blocksize);IvParameterSpec ivSpec = new IvParameterSpec(iv);Cipher cipher = Cipher.getInstance(algorithm + "/CBC/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);return cipher.doFinal(c);}/** * 加密 */public byte[] encrypt(byte[] iv, byte[] plaintext)throws InvalidKeyException, NoSuchAlgorithmException,NoSuchPaddingException, InvalidAlgorithmParameterException,IllegalBlockSizeException, BadPaddingException {IvParameterSpec ivSpec = new IvParameterSpec(iv);Cipher cipher = Cipher.getInstance(algorithm + "/CBC/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);this.blocksize = cipher.getBlockSize();byte[] c = cipher.doFinal(plaintext);byte[] ivAndCiphertext = new byte[c.length + this.blocksize];System.arraycopy(iv, 0, ivAndCiphertext, 0, this.blocksize);System.arraycopy(c, 0, ivAndCiphertext, this.blocksize, c.length);return ivAndCiphertext;}public Key generateKey(byte[] key) throws Exception {if (key == null) {// 随机生成密钥KeyGenerator keygen = KeyGenerator.getInstance(algorithm);SecureRandom random = new SecureRandom();keygen.init(random);return keygen.generateKey();} else {// 从一组固定的原始数据(也许是由口令或者随机键产生的)生成密钥// SecretKeyFactory keyFactory =// SecretKeyFactory.getInstance(algorithm);// SecretKeySpec keySpec = new SecretKeySpec(key, algorithm);// return keyFactory.generateSecret(keySpec);Key secretKey = new SecretKeySpec(key, algorithm);return secretKey;}}public void setAlgorithm(String algorithm) {this.algorithm = algorithm;}public void setKey(Key key) {this.key = key;}}public class Change {// 将字符转化为字节public static byte[] charToByte(char ch) {int temp = (int) ch;byte[] b = new byte[2];// 将高8位放在b[0],将低8位放在b[1]for (int i = 1; i > -1; i--) {b[i] = (byte) (temp & 0xFF);// 低8位// 向右移8位temp >>= 8;}return b;}// 将字节转化为比特数组public static byte[] byteToBitArray(byte b) {// 强制转换成int?int temp = (int) b;byte[] result = new byte[8];for (int i = 7; i > -1; i--) {result[i] = (byte) (temp & 0x01);temp >>= 1;}return result;}// 将二维比特数组转化为字节public static byte bitToByteArray(byte[] b) {byte result;result = (byte) (b[7] | b[6] << 1 | b[5] << 2 | b[4] << 3 | b[3] << 4| b[2] << 5 | b[1] << 6 | b[0] << 7);return result;}public static void main(String[] args) {for (byte b : charToByte('a')) {System.out.println(b);}}// 将字节转化为字符public static char byteToChar(byte[] b) {int s = 0;if (b[0] > 0) {s += b[0];}if (b[0] < 0) {s += 256 + b[0];}s *= 256;if (b[1] > 0) {s += b[1];}if (b[1] < 0) {s += 256 + b[1];}char ch = (char) s;return ch;}public static String byteToHexString(byte b) {String hex = "";hex = Integer.toHexString(b & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}return hex;}public static String bytesToHexString(byte[] bs) {StringBuffer sb = new StringBuffer();String hex = "";for (int i = 0; i < bs.length; i++) {hex = Integer.toHexString(bs[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}sb.append(hex);}return sb.toString();}public static byte[] hexStringToBytes(String in) {byte[] arrB = in.getBytes();int iLen = arrB.length;// 两个字符表示一个字节,所以字节数组长度是字符串长度除以2byte[] arrOut = new byte[iLen / 2];for (int i = 0; i < iLen; i = i + 2) {String strTmp = new String(arrB, i, 2);arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);}return arrOut;}}import java.security.Key;import org.junit.Test;public class DESCoderTest {@Testpublic void test2() throws Exception {Encryptor e = new Encryptor();e.setAlgorithm(Encryptor.ALGORITHM_THREEDES);Key key = e.generateKey(null);System.out.println("密钥为(hex):"+ Change.bytesToHexString(key.getEncoded()));e.setKey(key);String plaintext = "jlkasffdspfk阿斯达";System.out.println("明文为:\n" + plaintext);System.out.println("明文(hex)为:\n"+ Change.bytesToHexString(plaintext.getBytes()));String iv = "000a0a0a0a0202aa";String ivAndCiphertext = Change.bytesToHexString(e.encrypt(Change.hexStringToBytes(iv), plaintext.getBytes()));System.out.println("加密后:\n" + ivAndCiphertext);byte[] decrypt = e.decrypt(Change.hexStringToBytes(ivAndCiphertext));System.out.println("解密后(hex):\n" + Change.bytesToHexString(decrypt));System.out.println("解密后明文为:\n" + new String(decrypt));decrypt = e.decrypt(Change.hexStringToBytes(ivAndCiphertext));System.out.println("解密后(hex):\n" + Change.bytesToHexString(decrypt));System.out.println("解密后明文为:\n" + new String(decrypt));}@Testpublic void testAES() throws Exception {Encryptor e = new Encryptor();e.setAlgorithm(Encryptor.ALGORITHM_AES);Key key = e.generateKey(null);System.out.println("密钥为(hex):"+ Change.bytesToHexString(key.getEncoded()));e.setKey(key);String plaintext = "jlkasffdspfk阿斯达";System.out.println("明文为:\n" + plaintext);System.out.println("明文(hex)为:\n"+ Change.bytesToHexString(plaintext.getBytes()));String iv = "000a0a0a0a0202aa000a0a0a0a0202aa";String ivAndCiphertext = Change.bytesToHexString(e.encrypt(Change.hexStringToBytes(iv), plaintext.getBytes()));System.out.println("加密后:\n" + ivAndCiphertext);byte[] decrypt = e.decrypt(Change.hexStringToBytes(ivAndCiphertext));System.out.println("解密后(hex):\n" + Change.bytesToHexString(decrypt));System.out.println("解密后明文为:\n" + new String(decrypt));decrypt = e.decrypt(Change.hexStringToBytes(ivAndCiphertext));System.out.println("解密后(hex):\n" + Change.bytesToHexString(decrypt));System.out.println("解密后明文为:\n" + new String(decrypt));}}

        测试结果如下:
密钥为(hex):5ee9858f5b8020f168a4f8d9e3e9405d4f7f2620f2ea4aab
明文为:
jlkasffdspfk阿斯达
明文(hex)为:
6a6c6b61736666647370666bb0a2cbb9b4ef
加密后:
000a0a0a0a0202aae094fd8543a17fd66b6c9f619a965dfe2e573d93dfa392ca
解密后(hex):
6a6c6b61736666647370666bb0a2cbb9b4ef
解密后明文为:
jlkasffdspfk阿斯达
解密后(hex):
6a6c6b61736666647370666bb0a2cbb9b4ef
解密后明文为:
jlkasffdspfk阿斯达
密钥为(hex):0bbd345a9d9f0007931d2b01dfb8533c
明文为:
jlkasffdspfk阿斯达
明文(hex)为:
6a6c6b61736666647370666bb0a2cbb9b4ef
加密后:
000a0a0a0a0202aa000a0a0a0a0202aa9e61715cb05a74fc7f6e2e63092391a56e9ad922e370a107f99335a32cafcb09
解密后(hex):
6a6c6b61736666647370666bb0a2cbb9b4ef
解密后明文为:
jlkasffdspfk阿斯达
解密后(hex):
6a6c6b61736666647370666bb0a2cbb9b4ef
解密后明文为:
jlkasffdspfk阿斯达

原创粉丝点击