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

        最近对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;
		// 两个字符表示一个字节,所以字节数组长度是字符串长度除以2
		byte[] 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 {

	@Test
	public 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));
	}

	@Test
	public 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阿斯达

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值