java 加解密算法

15 篇文章 0 订阅

一,Base64

算法的实现:

定义:基于64个字符的编码算法

-JDK

jdk1.6之前用sun/oracle jdk里面的sun.misc.BASE64Encoder,注意不能直接调用,需要加入%JAVA_HOME%\jre\lib\rt.jar

	public static void jdkBase64() throws IOException{
		BASE64Encoder encoder = new BASE64Encoder();
		String encode = encoder.encode(src.getBytes());
		System.out.println("encode:"+encode);
		
		BASE64Decoder decoder = new BASE64Decoder();
		byte[] bytes = decoder.decodeBuffer(encode);
		System.out.println("decode:"+new String(bytes));
	}
	

jdk1.6的实现:

public static void jdk1_6Base64(){
		String encode = DatatypeConverter.printBase64Binary(src.getBytes());
		System.out.println(encode);
		
		byte[] decode = DatatypeConverter.parseBase64Binary(encode);
		System.out.println("encode:"+new String(decode));
	}
jdk1.8的实现:

public static void jdk1_8Base64(){
		byte[] encode = java.util.Base64.getEncoder().encode(src.getBytes());
		System.out.println("encode:"+new String(encode));
		
		byte[] decode = java.util.Base64.getDecoder().decode(encode);
		System.out.println("encode:"+new String(decode));
	}

-Commons Codec

	public static void commonsCodecBase64(){
		byte[] encodeBytes = Base64.encodeBase64(src.getBytes());
		System.out.println("encode:"+new String(encodeBytes));
		
		byte[] decodeBytes = Base64.decodeBase64(encodeBytes);
		System.out.println("decode:"+new String(decodeBytes));

	}

-BuuncyCastle的实现:

public static void bouncyCastleBase64(){
		byte[] encodeBytes =org.bouncycastle.util.encoders.Base64.encode(src.getBytes());
		System.out.println("encode:"+new String(encodeBytes));
		
		byte[] decodeBytes = org.bouncycastle.util.encoders.Base64.decode(encodeBytes);
		System.out.println("decode:"+new String(decodeBytes));
	
	}
应用场景:e-mail,密钥,证书文件

二,消息摘要算法(数字签名的核心算法)

1,MD(Message Digest) 消息摘要

2,SHA(Secure Hash Algorithm) 安全散列

2,MAC(Message Authentication Code) 消息认证码

主要作用:验证数据的完整性

MD家族:(128位摘要信息)

-MD2,MD4,MD5

MD2 JDK的实现:

public static void jdkMD2(){
		try {
			MessageDigest md = MessageDigest.getInstance("MD2");
			byte[] md2Bytes = md.digest(src.getBytes());
			System.out.println("jdk md2:"+bytes2hex(md2Bytes));

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}

public static void commonsCodecMD2(){
		//commonsCodec并没有自己实现md2算法,而是使用的jdk的实现
		System.out.println("commonsCodec md2:"+DigestUtils.md2Hex(src.getBytes()));
	}

MD4 Bouncy Castle(jdk 并没有提供md4)的实现:

public static void bouncyCastleMD4(){
		//提供Providerjdk
		Security.addProvider(new BouncyCastleProvider());
		try {
			MessageDigest md4 = MessageDigest.getInstance("MD4");
			byte[] md4Bytes = md4.digest(src.getBytes());
			System.out.println("bouncyCastle md4:"+bytes2hex(md4Bytes));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		
		//bouncyCastle自己的md4的实现
		Digest digest = new MD4Digest();
		digest.update(src.getBytes(), 0, src.getBytes().length);
		byte[] md4Bytes = new byte[digest.getDigestSize()];
		digest.doFinal(md4Bytes, 0);
		System.out.println("bouncyCastle md4:"+bytes2hex(md4Bytes));
	}

MD5 JDK的实现:

public static void jdkMD5(){
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			byte[] md5Bytes = md.digest(src.getBytes());
			System.out.println("jdk md5:"+bytes2hex(md5Bytes));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}
public static void commonsCodecMD5(){
		//commonsCodec并没有自己实现md5算法,而是使用的jdk的实现
		System.out.println("commonsCodec md5:"+DigestUtils.md5Hex(src.getBytes()));
	}

SHA:

-SHA1:160位 JDK

-SHA2(SHA-224(224位) JDK,Bouncy Castle, SHA-256 (256位) jdk, SHA-384(384位) jdk, SHA-512(512位) jdk)

SHA1 JDK:

	public static void jdkSHA1() {
		try {
			MessageDigest md = MessageDigest.getInstance("SHA");
			md.update(src.getBytes());
			byte[] bytes = md.digest();
			System.out.println("jdkSHA1:" + bytes2hex(bytes));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}
SHA-224 JDK,BouncyCastle的代码实现:

public static void jdkSHA224() {
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-224");
			md.update(src.getBytes());
			byte[] bytes = md.digest();
			System.out.println("jdkSHA224:" + bytes2hex(bytes));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}
public static void bouncyCastleSHA224() {

		try {
			Security.addProvider(new BouncyCastlePQCProvider());
			MessageDigest md = MessageDigest.getInstance("SHA-224");
			md.update(src.getBytes());
			byte[] bytes = md.digest();
			System.out.println("bouncyCastleSHA224:" + bytes2hex(bytes));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}

		Digest digest = new SHA224Digest();
		digest.update(src.getBytes(), 0, src.getBytes().length);
		byte[] bytes = new byte[digest.getDigestSize()];
		digest.doFinal(bytes, 0);
		System.out.println("bouncyCastleSHA224:" + bytes2hex(bytes));
	}

SHA-256 BouncyCastle的代码实现:

public static void bouncyCastleSHA256() {
		Digest digest = new SHA256Digest();
		digest.update(src.getBytes(), 0, src.getBytes().length);
		byte[] bytes = new byte[digest.getDigestSize()];
		digest.doFinal(bytes, 0);
		System.out.println("bouncyCastleSHA256:" + bytes2hex(bytes));
	}
SHA-384 JDK的代码实现:

public static void jdkSHA384(){
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-384");
			md.update(src.getBytes());
			byte[] bytes = md.digest();
			System.out.println("jdkSHA384" + bytes2hex(bytes));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}
SHA512 CommonsCodec的代码实现:

public static void CommonsCodec512() {
		System.out.println("CommonsCodec512:" + DigestUtils.sha512Hex(src));
	}
MAC(HMAC (keyed-hash message authentication code 含有密钥的散列函数算法))

融合MD,SHA

-MD系列:HmacMD2(128位,Bouncy Castle),HmacMD4(128位,Bouncy Castle),HmacMD5(128位,jdk)

-SHA系列:HmacSHA1(160位,jdk),HmacSHA224(224位,Bouncy Castle),HmacSHA256(256位,jdk),HmacSHA384(384位,jdk),HmacSHA512(512位,jdk)

HmacMD5 JDK的代码实现:

public static void jdkHmacMD5() {
		try {
			// 初始化KeyGenerator
			KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
			// 产生密钥
			SecretKey secretKey = keyGenerator.generateKey();
			// 获得密钥
			byte[] key = secretKey.getEncoded();
			// 还原密钥
			SecretKey restoreSecretKey = new SecretKeySpec(key, "HmacMD5");
			// 实例化MAC
			Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());
			// 初始MAC
			mac.init(restoreSecretKey);
			// 执行摘要
			byte[] hmacMD5Bytes = mac.doFinal(src.getBytes());

			System.out.println("jdkhmacmd5:" + bytes2hex(hmacMD5Bytes));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

HmacMD5 bouncyCastle的代码实现:

public static void bouncyCastleHmacMD5() {
		HMac hmac = new HMac(new MD5Digest());
		hmac.init(new KeyParameter(Hex.decode("aaaaaaaaaa")));
		hmac.update(src.getBytes(), 0, src.getBytes().length);
		byte[] hmacMD5Bytes = new byte[hmac.getMacSize()];
		hmac.doFinal(hmacMD5Bytes, 0);
		System.out.println("bouncyCastleHmacMD5:" + bytes2hex(hmacMD5Bytes));

	}
这2中由于密钥的不同摘要之后的结果不一样。

如果jdk的实现也是10个a那么摘要的结果就和bouncy Castle一样:

public static void jdkHmacMD5() {
		try {
			// 初始化KeyGenerator
			KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
			// 产生密钥
			SecretKey secretKey = keyGenerator.generateKey();
			// 获得密钥
//			byte[] key = secretKey.getEncoded();s
			byte[] key = hexStr2ByteArray("aaaaaaaaaa");
			// 还原密钥
			SecretKey restoreSecretKey = new SecretKeySpec(key, "HmacMD5");
			// 实例化MAC
			Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());
			// 初始MAC
			mac.init(restoreSecretKey);
			// 执行摘要
			byte[] hmacMD5Bytes = mac.doFinal(src.getBytes());

			System.out.println("jdkhmacmd5:" + bytes2hex(hmacMD5Bytes));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
byte数组转16进制的的实现:

private static final String HEX = "0123456789abcdef";

	public static String bytes2hex(byte[] bytes) {
		StringBuilder sb = new StringBuilder(bytes.length * 2);
		for (byte b : bytes) {
			// 取出这个字节的高4位,然后与0x0f与运算,得到一个0-15之间的数据,通过HEX.charAt(0-15)即为16进制数
			sb.append(HEX.charAt((b >> 4) & 0x0f));
			// 取出这个字节的低位,与0x0f与运算,得到一个0-15之间的数据,通过HEX.charAt(0-15)即为16进制数
			sb.append(HEX.charAt(b & 0x0f));
		}

		return sb.toString();
	}
16进制转byte数组的实现:

public static byte[] hexStr2ByteArray(String hexString) {
		if (hexString == null || hexString.equals(""))
			throw new IllegalArgumentException("this hexString must not be empty");

		hexString = hexString.toLowerCase();
		final byte[] byteArray = new byte[hexString.length() / 2];
		int k = 0;
		for (int i = 0; i < byteArray.length; i++) {
			// 因为是16进制,最多只会占用4位,转换成字节需要两个16进制的字符,高位在先
			// 将hex 转换成byte "&" 操作为了防止负数的自动扩展
			// hex转换成byte 其实只占用了4位,然后把高位进行右移四位
			// 然后“|”操作 低四位 就能得到 两个 16进制数转换成一个byte.
			//
			byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
			byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
			byteArray[i] = (byte) (high << 4 | low);
			k += 2;
		}
		return byteArray;
	}
三,对称加密算法:

加密密钥=解密密钥

-DES

   -3DES

-AES

-PBE

-IDEA

DES(Data Encryption Standard) 数据加密标准(新项目不推荐使用,安全性较差)


JDK代码实现:

public static void jdkDES(){
		try {
			//生成key
			KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
			keyGenerator.init(56);
			SecretKey secretKey = keyGenerator.generateKey();
			byte[] byteKey = secretKey.getEncoded();
			
			//key转换
			DESKeySpec desKeySpec = new DESKeySpec(byteKey);
			SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
			Key convertSecretKey = factory.generateSecret(desKeySpec);
		
			//加密  Cipher.getInstance("加解密算法/工作方式/填充方式")
			Cipher ciper = Cipher.getInstance("DES/ECB/PKCS5Padding");
			ciper.init(Cipher.ENCRYPT_MODE, convertSecretKey);
			byte[] bytes = ciper.doFinal(src.getBytes());
			System.out.println("jdk des encrypt:"+Hex.encodeHexString(bytes));
		
			//解密
			ciper.init(Cipher.DECRYPT_MODE,convertSecretKey);
			bytes = ciper.doFinal(bytes);
			System.out.println("jdk des decrypt:"+new String(bytes));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
bouncyCastle的代码实现:

public static void bouncyCastleDES(){
		try {
			Security.addProvider(new BouncyCastleProvider());
			
			
			//生成key
			KeyGenerator keyGenerator = KeyGenerator.getInstance("DES","BC");
			keyGenerator.init(56);
			SecretKey secretKey = keyGenerator.generateKey();
			byte[] byteKey = secretKey.getEncoded();
			
			//key转换
			DESKeySpec desKeySpec = new DESKeySpec(byteKey);
			SecretKeyFactory factory = SecretKeyFactory.getInstance("DES","BC");
			Key convertSecretKey = factory.generateSecret(desKeySpec);
		
			//加密  Cipher.getInstance("加解密算法/工作方式/填充方式")
			Cipher ciper = Cipher.getInstance("DES/ECB/PKCS5Padding","BC");
			ciper.init(Cipher.ENCRYPT_MODE, convertSecretKey);
			byte[] bytes = ciper.doFinal(src.getBytes());
			System.out.println("bouncyCastle des encrypt:"+Hex.encodeHexString(bytes));
		
			//解密
			ciper.init(Cipher.DECRYPT_MODE,convertSecretKey);
			bytes = ciper.doFinal(bytes);
			System.out.println("bouncyCastle des decrypt:"+new String(bytes));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
DES的算法应用流程图:

3DES(3重DES)

出现的原因:DES违反了柯克霍夫原则(DES加密算法半公开)

3DES的好处:

1,密钥长度增强

2,迭代次数增多

JDK

	public static void jdk3DES(){
		try {
			//生成key
			KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
//			keyGenerator.init(168);
			keyGenerator.init(new SecureRandom());//根据不同的算法生成相应长度的key
			SecretKey secretKey = keyGenerator.generateKey();
			byte[] byteKey = secretKey.getEncoded();
			
			//key转换
			DESedeKeySpec desKeySpec = new DESedeKeySpec(byteKey);
			SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
			Key convertSecretKey = factory.generateSecret(desKeySpec);
		
			//加密  Cipher.getInstance("加解密算法/工作方式/填充方式")
			Cipher ciper = Cipher.getInstance("DESede/ECB/PKCS5Padding");
			ciper.init(Cipher.ENCRYPT_MODE, convertSecretKey);
			byte[] bytes = ciper.doFinal(src.getBytes());
			System.out.println("jdk 3des encrypt:"+Hex.encodeHexString(bytes));
		
			//解密
			ciper.init(Cipher.DECRYPT_MODE,convertSecretKey);
			bytes = ciper.doFinal(bytes);
			System.out.println("jdk 3des decrypt:"+new String(bytes));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
bouncyCastle

public static void bouncyCastle3DES(){
		try {
			Security.addProvider(new BouncyCastleProvider());
			
			//生成key
			KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede","BC");
//			keyGenerator.init(168);
			keyGenerator.init(new SecureRandom());//根据不同的算法生成相应长度的key
			SecretKey secretKey = keyGenerator.generateKey();
			byte[] byteKey = secretKey.getEncoded();
			
			//key转换
			DESedeKeySpec desKeySpec = new DESedeKeySpec(byteKey);
			SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede","BC");
			Key convertSecretKey = factory.generateSecret(desKeySpec);
		
			//加密  Cipher.getInstance("加解密算法/工作方式/填充方式")
			Cipher ciper = Cipher.getInstance("DESede/ECB/PKCS5Padding","BC");
			ciper.init(Cipher.ENCRYPT_MODE, convertSecretKey);
			byte[] bytes = ciper.doFinal(src.getBytes());
			System.out.println("bouncyCastle 3des encrypt:"+Hex.encodeHexString(bytes));
		
			//解密
			ciper.init(Cipher.DECRYPT_MODE,convertSecretKey);
			bytes = ciper.doFinal(bytes);
			System.out.println("bouncyCastle 3des decrypt:"+new String(bytes));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

3DES算法应用流程同上DES

AES

出现的原因:DES的算法那存在安全,3DES效率较低

AES是目前使用最多的对称加密算法(DES的替代者)

AES通常用于移动通讯系统的加密以及基于SSH协议的软件

jdk代码实现:

	public static void jdkAES(){
		try {
			//生成key
			KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
			keyGenerator.init(128);
			SecretKey secretKey = keyGenerator.generateKey();
			byte[] byteKey = secretKey.getEncoded();
			
			//key转换
			Key key = new SecretKeySpec(byteKey, "AES");
		
			//加密  Cipher.getInstance("加解密算法/工作方式/填充方式")
			Cipher ciper = Cipher.getInstance("AES/ECB/PKCS5Padding");
			ciper.init(Cipher.ENCRYPT_MODE, key);
			byte[] bytes = ciper.doFinal(src.getBytes());
			System.out.println("jdk aes encrypt:"+Hex.encodeHexString(bytes));
	
			//解密
			ciper.init(Cipher.DECRYPT_MODE,key);
			bytes = ciper.doFinal(bytes);
			System.out.println("jdk aes decrypt:"+new String(bytes));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
bouncyCastle代码实现:

public static void bouncyCastleAES(){
		try {
			Security.addProvider(new BouncyCastleProvider());
			
			//生成key
			KeyGenerator keyGenerator = KeyGenerator.getInstance("AES","BC");
			keyGenerator.init(128);
			SecretKey secretKey = keyGenerator.generateKey();
			byte[] byteKey = secretKey.getEncoded();
			
			//key转换
			Key key = new SecretKeySpec(byteKey, "AES");
		
			//加密  Cipher.getInstance("加解密算法/工作方式/填充方式")
			Cipher ciper = Cipher.getInstance("AES/ECB/PKCS5Padding","BC");
			ciper.init(Cipher.ENCRYPT_MODE, key);
			byte[] bytes = ciper.doFinal(src.getBytes());
			System.out.println("bouncyCastle aes encrypt:"+Hex.encodeHexString(bytes));
		
			//解密
			ciper.init(Cipher.DECRYPT_MODE,key);
			bytes = ciper.doFinal(bytes);
			System.out.println("bouncyCastle aes decrypt:"+new String(bytes));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
AES算法应用流程图:

PBE(Password Based Encryption)基于口令的加密

对已有算法的包装

加盐(加扰码)

JDK代码实现:

public static void jdkPBE(){
		try {
			//初始化盐
			SecureRandom random = new SecureRandom();
			byte[] salt = random.generateSeed(8);
			
			//口令与秘钥
			String password = "siy";
			PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
			SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
			Key key = factory.generateSecret(pbeKeySpec);
			
			//加密
			PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 100);
			Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
			cipher.init(Cipher.ENCRYPT_MODE, key,pbeParameterSpec);
			byte[] result = cipher.doFinal(src.getBytes());
			System.out.println("jdk pbe enctpy:"+Hex.encodeHexString(result));
			
			//解密
			cipher.init(Cipher.DECRYPT_MODE, key,pbeParameterSpec);
			result = cipher.doFinal(result);
			System.out.println("jdk pbe dectpy:"+new String(result));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
bouncyCastle代码实现:

public static void bouncyCastlePBE(){
			try {
				Security.addProvider(new BouncyCastleProvider());
				
				//初始化盐
				SecureRandom random = new SecureRandom();
				byte[] salt = random.generateSeed(8);
				
				//口令与秘钥
				String password = "siy";
				PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
				SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWithMD5AndDES","BC");
				Key key = factory.generateSecret(pbeKeySpec);
				
				//加密
				PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 100);
				Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES","BC");
				cipher.init(Cipher.ENCRYPT_MODE, key,pbeParameterSpec);
				byte[] result = cipher.doFinal(src.getBytes());
				System.out.println("bouncyCastle pbe enctpy:"+Hex.encodeHexString(result));
				
				//解密
				cipher.init(Cipher.DECRYPT_MODE, key,pbeParameterSpec);
				result = cipher.doFinal(result);
				System.out.println("bouncyCastle pbe dectpy:"+new String(result));
			} catch (Exception e) {
				e.printStackTrace();
			}
	}
PBF算法应用流程图:

四,非对称加密算法

DH(Diffie-Hellman)密钥交换算法

RSA-基于因子分解

ElGamal-基于离散对数

ECC(Elliptical Curve Cryptography)-椭圆曲线加密

DH密钥交换算法

jdk代码实现:

/**
	 * 初始化发送方密钥
	 * -KeyPairGenerator //通过KeyPairGenerator来得到KeyPair类的对象 KeyPairGenerator.getInstance("DH");
	 * -KeyPair  //密钥对(包含公钥,私钥)
	 * -PublicKey //公钥
	 * 
	 * 通过KeyPairGenerator来得到KeyPair类的对象
	 * 
	 * 
	 * 初始化接收方密钥
	 * -KeyFactory //密钥工厂,用来生成密钥,通过某种规范来还原密钥
	 * -X509EncodeKeySpec //根据ASN.1标准进行密钥的编码
	 * -DHPublicKey //DH类PublicKey的具体形式
	 * -DHParameterSpec//DH参数的集合
	 * -KeyPairGenerator
	 * -PrivateKey//私钥
	 * 
	 * 
	 * 密钥构建
	 * -KeyAgreement//提供密钥一致性(或密钥交换)协议的功能
	 * -SecretKey//密码密钥 生成一个分组的秘密密钥
	 * -KeyFactory
	 * -X509EncodedKeySpec
	 * -PublicKey
	 * 
	 * 加密,解密
	 * -Cipher
	 **/
	public static void jdkDH(){
		try {
			//1,初始化发送方密钥
			KeyPairGenerator sendKeyPairGenerator = KeyPairGenerator.getInstance("DH");
			sendKeyPairGenerator.initialize(512);
			KeyPair senderkeyPair = sendKeyPairGenerator.generateKeyPair();
			byte[] senderPublicKeyEnc = senderkeyPair.getPublic().getEncoded();//发送方公钥,发送给接收方
			
			//2,初始化接受方密钥
			KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH");
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKeyEnc);
			PublicKey receiverPublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec);
			DHParameterSpec dhParameterSpec = ((DHPublicKey)receiverPublicKey).getParams();
			KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");
			receiverKeyPairGenerator.initialize(dhParameterSpec);
			KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();
			PrivateKey receiverPrivateKey = receiverKeyPair.getPrivate();
			byte[] receiverPublic = receiverKeyPair.getPublic().getEncoded();
			
			//3,密钥构建
			KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");
			receiverKeyAgreement.init(receiverPrivateKey);
			receiverKeyAgreement.doPhase(receiverPublicKey, true);
			SecretKey receiverDesKey = receiverKeyAgreement.generateSecret("DES");
			
			KeyFactory sendKeyFactory = KeyFactory.getInstance("DH");
			x509EncodedKeySpec = new X509EncodedKeySpec(receiverPublic);
			PublicKey senderPublicKey = sendKeyFactory.generatePublic(x509EncodedKeySpec);			
			KeyAgreement senderKeyAgreement = KeyAgreement.getInstance("DH");
			senderKeyAgreement.init(senderkeyPair.getPrivate());
			senderKeyAgreement.doPhase(senderPublicKey, true);
			SecretKey senderDesKey = senderKeyAgreement.generateSecret("DES");
			
			if(Objects.equals(receiverDesKey, senderDesKey)){
				System.out.println("双方密钥相同");
			}
			
			//4,加密
			Cipher cipher = Cipher.getInstance("DES");
			cipher.init(Cipher.ENCRYPT_MODE, senderDesKey);
			byte[] result = cipher.doFinal(src.getBytes());
			System.out.println("jdk dh encrypt:"+Base64.getEncoder().encodeToString(result));
			
			//5,解密
			cipher.init(Cipher.DECRYPT_MODE, receiverDesKey);
			result = cipher.doFinal(result);
			System.out.println("jdk dh decrypt:"+new String(result));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
DH算法应用流程图:

RSA

唯一广泛接受并实现

数据加密&数字签名

公钥加密,私钥解密

私钥加密,公钥解密

缺点:有点慢

jdk代码实现:

public static void jdkRAS() {
		try {
			// 1,初始化密钥
			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
			keyPairGenerator.initialize(512);
			KeyPair keyPair = keyPairGenerator.generateKeyPair();
			RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
			RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
			System.out.println("rsaPublicKey:" + Base64.getEncoder().encodeToString(rsaPublicKey.getEncoded()));
			System.out.println("rsaPrivateKey:" + Base64.getEncoder().encodeToString(rsaPrivateKey.getEncoded()));

			// 2,私钥加密,公钥解密 - 加密
			PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.ENCRYPT_MODE, privateKey);
			byte[] result = cipher.doFinal(src.getBytes());
			System.out.println("私钥加密,公钥解密 - 加密:" + Base64.getEncoder().encodeToString(result));

			// 3,私钥加密,公钥解密 - 解密
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
			keyFactory = KeyFactory.getInstance("RSA");
			PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, publicKey);
			result = cipher.doFinal(result);
			System.out.println("私钥加密,公钥解密 - 解密:" + new String(result));

			// 4,公钥加密,私钥解密 - 加密
			x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
			keyFactory = KeyFactory.getInstance("RSA");
			publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.ENCRYPT_MODE, publicKey);
			result = cipher.doFinal(src.getBytes());
			System.out.println("公钥加密,私钥解密 - 加密:" + Base64.getEncoder().encodeToString(result));

			// 5,公钥加密,私钥解密 - 解密
			pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
			keyFactory = KeyFactory.getInstance("RSA");
			privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, privateKey);
			result = cipher.doFinal(result);
			System.out.println("公钥加密,私钥解密 - 解密:" + new String(result));

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
RSA算法的应用流程图:

ElGamal(jdk没有提供实现,需要使用bouncyCastle架包)

只支持公钥加密私钥解密,不支持私钥加密,公钥解密

bouncyCastle的Elmal的代码实现:

public static void bouncyCastleElGamal() {
		try {
			// 加入对BouncyCastle支持
			Security.addProvider(new BouncyCastleProvider());

			// 公钥加密,私钥解密(不能私钥加密,公钥解密)
			// 1,初始化密钥
			AlgorithmParameterGenerator algorithmParameterGenerator = AlgorithmParameterGenerator
					.getInstance("ElGamal");
			// 初始化参数生成器
			algorithmParameterGenerator.init(256);
			// 生成算法参数
			AlgorithmParameters algorithmParameters = algorithmParameterGenerator.generateParameters();
			// 构建参数材料
			DHParameterSpec dhParameterSpec = algorithmParameters.getParameterSpec(DHParameterSpec.class);
			// 实例化密钥生成器
			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ElGamal");
			// 初始化密钥对生成器
			keyPairGenerator.initialize(dhParameterSpec, new SecureRandom());
			KeyPair keyPair = keyPairGenerator.generateKeyPair();
			// 公钥
			PublicKey elGamalPublicKey = keyPair.getPublic();
			// 私钥
			PrivateKey elGamalPrivateKey = keyPair.getPrivate();
			System.out.println("publicKey:" + Base64.getEncoder().encodeToString(elGamalPublicKey.getEncoded()));
			System.out.println("privateKey:" + Base64.getEncoder().encodeToString(elGamalPrivateKey.getEncoded()));

			// 2.私钥解密、公钥加密 ---- 加密
			// 初始化公钥
			// 密钥材料转换
			X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(elGamalPublicKey.getEncoded());
			// 实例化密钥工厂
			KeyFactory keyFactory = KeyFactory.getInstance("Elgamal");
			// 产生公钥
			PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
			// 数据加密
			Cipher cipher = Cipher.getInstance("Elgamal");
			// Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
			cipher.init(Cipher.ENCRYPT_MODE, publicKey);
			byte[] result = cipher.doFinal(src.getBytes());
			System.out.println("公钥加密,私钥解密:" + Base64.getEncoder().encodeToString(result));

			// 3.私钥解密、公钥加密 ---- 解密
			PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(elGamalPrivateKey.getEncoded());
			keyFactory = KeyFactory.getInstance("Elgamal");
			PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
			cipher = Cipher.getInstance("Elgamal");
			// cipher = Cipher.getInstance(keyFactory.getAlgorithm());
			cipher.init(Cipher.DECRYPT_MODE, privateKey);
			result = cipher.doFinal(result);
			System.out.println("公钥加密,私钥解密:" + new String(result));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
如果直接运行这个加密方法会报如下错误:


这个是由于无政策限制权限文件(local_policy.jar、US_export_policy.jar)引起的。

这2个文件的位置在jdk\jre\lib\security和jre\lib\security下

Oracle在其官方网站上提供了无政策限制权限文件(Unlimited Strength Jurisdiction Policy Files),我们只需要将其下载下来然后替换掉就可以了。

jdk1.6下载地址:

http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

jdk1.7下载地址:

http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

jdk1.8下载地址:

http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

替换后运行:

ElGamal算法应用流程图:

五,数字签名算法

定义:带有密钥(公钥,私钥)的消息摘要算法

作用:验证数据的完整性,认证数据来源,抗否认

私钥签名,公钥验证

RAS,DSA,ECDSA

RSA

MD,SHA两类

jdk代码实现:

public static void jdkRAS(){
		try {
			//私钥签名,公钥验证
			
			//1,初始化密钥
			KeyPairGenerator keyPairGeneratot = KeyPairGenerator.getInstance("RSA");
			keyPairGeneratot.initialize(512);
			KeyPair keyPair = keyPairGeneratot.generateKeyPair();
			RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
			RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();
			
			//2,执行签名
			PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			Signature signature = Signature.getInstance("MD5withRSA");
			signature.initSign(privateKey);
			signature.update(src.getBytes());
			byte[] result = signature.sign();
			System.out.println("jdk RSA sign:"+Base64.getEncoder().encodeToString(result));
			
			//3,验证签名
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());			
			keyFactory = KeyFactory.getInstance("RSA");
			PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			signature = Signature.getInstance("MD5withRSA");
			signature.initVerify(publicKey);
			signature.update(src.getBytes());
			boolean bool = signature.verify(result);
			System.out.println("jdk RSA verify:"+ bool);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
RSA数字签名算法的应用流程图:

DSA(Digital Signature Algorithm)数字签名算法标准

DSA仅包含数字签名,不包含加密

jdk代码的实现:

public static void jdkDSA(){
		try {
			//1,初始化密钥
			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");
			keyPairGenerator.initialize(512);
			KeyPair keyPair = keyPairGenerator.generateKeyPair();
			DSAPublicKey dsaPublicKey = (DSAPublicKey)keyPair.getPublic();
			DSAPrivateKey dsaPrivateKey = (DSAPrivateKey)keyPair.getPrivate();
			
			//2,执行签名
			PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(dsaPrivateKey.getEncoded());
			KeyFactory keyFactory = KeyFactory.getInstance("DSA");
			PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			Signature signature = Signature.getInstance("SHA1withDSA");
			signature.initSign(privateKey);
			signature.update(src.getBytes());
			byte[] result = signature.sign();
			System.out.println("jdk DSA sign:"+Base64.getEncoder().encodeToString(result));
			
			//3,验证签名
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey.getEncoded());			
			keyFactory = KeyFactory.getInstance("DSA");
			PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			signature = Signature.getInstance("SHA1withDSA");
			signature.initVerify(publicKey);
			signature.update(src.getBytes());
			boolean bool = signature.verify(result);
			System.out.println("jdk DSA verify:"+ bool);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
DSA数字签名算法的应用流程图:

ECDSA(Elliptic Curve Digital Signture Algorithm)椭圆曲线数字签名算法(jdk1.7)

优点:速度快,强度高,签名短

jdk代码实现:

public static void jdkECDSA(){
		try {
			//1,初始化密钥
			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
			keyPairGenerator.initialize(256);
			KeyPair keyPair = keyPairGenerator.generateKeyPair();
			ECPublicKey ecPublicKey = (ECPublicKey)keyPair.getPublic();
			ECPrivateKey ecPrivateKey = (ECPrivateKey)keyPair.getPrivate();
		
			//2,执行签名
			PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(ecPrivateKey.getEncoded());
			KeyFactory keyFactory = KeyFactory.getInstance("EC");
			PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			Signature signature = Signature.getInstance("SHA1withECDSA");
			signature.initSign(privateKey);
			signature.update(src.getBytes());
			byte[] result = signature.sign();
			System.out.println("jdk ECDSA sign:"+Base64.getEncoder().encodeToString(result));
			
			//3,验证签名
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(ecPublicKey.getEncoded());			
			keyFactory = KeyFactory.getInstance("EC");
			PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			signature = Signature.getInstance("SHA1withECDSA");
			signature.initVerify(publicKey);
			signature.update(src.getBytes());
			boolean bool = signature.verify(result);
			System.out.println("jdk ECDSA verify:"+ bool);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
ECDSA数字签名算法应用流程图:


终于敲完了!!!


完整例子项目代码在:http://download.csdn.net/detail/baidu_34012226/9695810

jdk1.8的无政策限制权限文件(local_policy.jar、US_export_policy.jar)在:http://download.csdn.net/detail/baidu_34012226/9695825

文件加密解密算法(Java源码) java,file,算法,加密解密,java源码 package com.crypto.encrypt; import java.security.SecureRandom; import java.io.*; import javax.crypto.spec.DESKeySpec; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.Cipher; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import javax.crypto.NoSuchPaddingException; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import java.lang.reflect.Constructor; import java.security.spec.KeySpec; import java.lang.reflect.InvocationTargetException; public class EncryptData { private String keyfile=null; public EncryptData() { } public EncryptData(String keyfile) { this.keyfile=keyfile; } /** * 加密文件 * @param filename String 源路径 * @param filenamekey String 加密后的路径 */ public void createEncryptData(String filename,String filenamekey) throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException, InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, IOException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException, IllegalStateException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException, InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, IOException { //验证keyfile if(keyfile==null || keyfile.equals("")) { throw new NullPointerException("无效的key文件路径"); } encryptData(filename,filenamekey); } /** * 加密类文件 * @param filename String 原始的类文件 * @param encryptfile String 加密后的类文件 * @throws IOException * @throws InvalidKeyException * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws IllegalStateException */ private void encryptData(String filename,String encryptfile) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, IllegalStateException, ClassNotFoundException, SecurityException, NoSuchMethodException, InvocationTargetException, IllegalArgumentException, IllegalAccessException, InstantiationException { byte data[]=Util.readFile(filename); // 执行加密操作 byte encryptedClassData[] = getencryptData(data); // 保存加密后的文件,覆盖原有的类文件。 Util.writeFile(encryptedClassData,encryptfile); } /** * 直接获得加密数据 * @param bytes byte[] * @throws IllegalStateException * @throws IllegalBlockSizeException * @throws BadPaddingException * @throws InvalidKeyException * @throws NoSuchPaddingException * @throws InvalidKeySpecException * @throws NoSuchAlgorithmException * @throws InstantiationException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException * @throws NoSuchMethodException * @throws SecurityException * @throws ClassNotFoundException * @throws IOException * @return byte[] */ public byte[] createEncryptData(byte[] bytes) throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchPaddingException, InvalidKeySpecException, NoSuchAlgorithmException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException, IOException { bytes=getencryptData(bytes); return bytes; } private byte[] getencryptData(byte[] bytes) throws IOException, ClassNotFoundException, SecurityException, NoSuchMethodException, InvocationTargetException, IllegalArgumentException, IllegalAccessException, InstantiationException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, IllegalStateException { // 产生一个可信任的随机数源 SecureRandom sr = new SecureRandom(); //从密钥文件key Filename中得到密钥数据 byte[] rawKeyData = Util.readFile(keyfile); // 从原始密钥数据创建DESKeySpec对象 Class classkeyspec=Class.forName(Util.getValue("keyspec")); Constructor constructor = classkeyspec.getConstructor(new Class[]{byte[].class}); KeySpec dks = (KeySpec) constructor.newInstance(new Object[]{rawKeyData}); // 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Util.getAlgorithm()); SecretKey key = keyFactory.generateSecret(dks); // Cipher对象实际完成加密操作 Cipher cipher = Cipher.getInstance(Util.getAlgorithm()); // 用密钥初始化Cipher对象 cipher.init(Cipher.ENCRYPT_MODE, key, sr); // 执行加密操作 bytes = cipher.doFinal(bytes); // 返回字节数组 return bytes; } /** * 设置key文件路径 * @param keyfile String */ public void setKeyFile(String keyfile) { this.keyfile=keyfile; } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值