Java常用加密算法 您所在的位置:网站首页 Java实现一个数字加密器 Java常用加密算法

Java常用加密算法

2023-10-28 10:03| 来源: 网络整理| 查看: 265

一、Base64

       Base64用于网络中传输的数据进行编码,严格意义上属于编码的格式,有64个字符的对应的编码,Base64就是将内容按照该格式进行编码。可以对数据编码和解码,是可逆的,安全度较低。 Base64可以使用JDk中自带的类实现,还可以使用Bouncy Castle(简称bc)或Commons Codec(简称cc)实现。

1.1 JDK自带类实现 import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Base64; public class Test { public static void main(String[] args) { // 原始数据 String str = "Hello World"; // 加密 Base64.Encoder encoder = Base64.getEncoder(); String encoderStr = encoder.encodeToString(str.getBytes("utf-8")); System.out.println("encoder: " + encoderStr); // 解密 Base64.Decoder decoder = Base64.getDecoder(); String decoderStr = new String(decoder.decode(encoderStr), "utf-8"); System.out.println("decoder: " + decoderStr); } } 二、摘要算法

       摘要算法主要分为MD,SHA和Hmac算法,摘要算法其实是用于效验数据完整性的,我们在下载某些文件时,会有MD5和SHA1值提供我们效验下载的文件是否完整,可以用于根据数据生成其唯一的摘要值,无法根据摘要值知道原数据,属于不可逆的。

2.1 MD 算法摘要长度实现方MD2128JDKMD5128JDK

JDK有MD2和MD5实现,使用的是MessageDigest类。(JDK没有MD4的实现)

import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Test { public static void main(String[] args) throws NoSuchAlgorithmException { // 原始字符 String data = "Hello World!"; // 编码 MessageDigest md = MessageDigest.getInstance("MD5"); byte[] digest = md.digest(data.getBytes()); // 转化为16进制编码 BigInteger bigInteger = new BigInteger(1, digest); System.out.println("JDK MD5: " + bigInteger.toString(16)); } } 2.2 SHA

安全摘要算法,常用的有如下几种:

算法摘要长度实现方SHA-1160JDKSHA-224224Bouncy CastleSHA2561256JDKSHA-384384JDKSHA-512512JDK import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Test { public static void main(String[] args) throws NoSuchAlgorithmException { // 原始字符 String data = "Hello World!"; // SHA-1 编码 MessageDigest md = MessageDigest.getInstance("SHA"); byte[] digest = md.digest(data.getBytes()); BigInteger bigInteger = new BigInteger(1, digest); System.out.println("JDK MD5: " + bigInteger.toString(16)); } } 2.3 Hmac

Hmac是一种含有密钥的摘要算法,也有简称mac,密钥不同摘要也不同。常用的有如下几种:

算法摘要长度实现方HmacMD2128Bouncy CastleHmacMD4128Bouncy CastleHmacMD5128JDKHmacSHA1160JDKHmacSHA224224Bouncy CastleHmacSHA256256JDKHmacSHA384384JDKHmacSHA512512JDK public class Test { public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException { // 原始字符 String data = "Hello World!"; // // 生成秘钥,也可以自定义秘钥 // KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5"); // SecretKey secretKey = keyGenerator.generateKey(); //产生密钥 // byte[] key = secretKey.getEncoded(); //获得密钥(默认生成) byte[] key = new byte[]{'a','a','a','a','a','a','a','a','a','a'}; // 手动生成密钥(十位) SecretKey secretKey2 = new SecretKeySpec(key, "HmacMD5"); // 还原密钥 Mac mac = Mac.getInstance(secretKey2.getAlgorithm()); // 实例化mac mac.init(secretKey2); // 初始化mac byte[] hmacMD5Bytes = mac.doFinal(data.getBytes()); // 生成摘要 BigInteger bigInteger = new BigInteger(1, hmacMD5Bytes); System.out.println("jdk hmacMD5: " + bigInteger.toString(16)); } } 三、对称加密

       严格意义上的加密算法,分为对称和非对称加密算法,所谓对称是说发送方和接收方的密钥是一样的。因为密钥一样所以安全性跟非对称比较来说就不太安全了 对称加密算法主要分为:DES , 3DES(3重DES) , AES(想要替代DES) , PBE(基于口令的对称算法)

3.1 DES 密钥长度默认工作方式填充方式实现方5656ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128NoPadding、PKCS5Padding、ISO10126PaddingJDK6456ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128PKCS7Padding、ISO1012d2Padding、X932Padding、ZeroBytePaddingBouncy Castle import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import java.math.BigInteger; public class Test { public static void main(String[] args) throws Exception { // 原始字符 String data = "Hello World!"; //生成key KeyGenerator keyGenerator=KeyGenerator.getInstance("DES"); keyGenerator.init(56); //指定key长度,同时也是密钥长度(56位) SecretKey secretKey = keyGenerator.generateKey(); //生成key的材料 byte[] key = secretKey.getEncoded(); //生成key // key转换成密钥(自己指定字节数组时需要转换) DESKeySpec desKeySpec=new DESKeySpec(key); SecretKeyFactory factory=SecretKeyFactory.getInstance("DES"); SecretKey key2 = factory.generateSecret(desKeySpec); //转换后的密钥 // 加密 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); //算法类型/工作方式/填充方式 cipher.init(Cipher.ENCRYPT_MODE, key2); //指定为加密模式 byte[] result = cipher.doFinal(data.getBytes()); BigInteger bigInteger = new BigInteger(1, result); System.out.println("jdkDES加密: "+ bigInteger.toString(16)); //转换为十六进制 // 解密 cipher.init(Cipher.DECRYPT_MODE, key2); //相同密钥,指定为解密模式 result = cipher.doFinal(result); //根据加密内容解密 System.out.println("jdkDES解密: " + new String(result)); //转换字符串 } } 3.2 3DES 密钥长度默认工作方式填充方式实现方112、168168ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128NoPadding、PKCS5Padding、ISO10126PaddingJDK128、192168ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128PKCS7Padding、ISO1012d2Padding、X932Padding、ZeroBytePaddingBouncy Castle import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import java.math.BigInteger; import java.security.SecureRandom; public class Test { public static void main(String[] args) throws Exception { // 原始字符 String data = "Hello World!"; // 生成key KeyGenerator keyGenerator=KeyGenerator.getInstance("DESede"); keyGenerator.init(112); //3DES需要112 or 168位 keyGenerator.init(new SecureRandom()); //或者使用这种方式默认长度,无需指定长度 SecretKey secretKey = keyGenerator.generateKey(); //生成key的材料 byte[] key = secretKey.getEncoded(); //生成key // key转换成密钥(自己指定字节数组时需要转换) DESedeKeySpec desKeySpec=new DESedeKeySpec(key); SecretKeyFactory factory=SecretKeyFactory.getInstance("DESede"); SecretKey key2 = factory.generateSecret(desKeySpec); //转换后的密钥 //加密 Cipher cipher=Cipher.getInstance("DESede/ECB/PKCS5Padding"); //算法类型/工作方式/填充方式 cipher.init(Cipher.ENCRYPT_MODE, key2); //指定为加密模式 byte[] result = cipher.doFinal(data.getBytes()); BigInteger bigInteger = new BigInteger(1, result); System.out.println("jdk3DES加密: " + bigInteger.toString(16)); //转换为十六进制 //解密 cipher.init(Cipher.DECRYPT_MODE, key2); //相同密钥,指定为解密模式 result = cipher.doFinal(result); //根据加密内容解密 System.out.println("jdk3DES解密: " + new String(result)); //转换字符串 } } 3.3 AES 密钥长度默认工作方式填充方式实现方112、192、256128ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128NoPadding、PKCS5Padding、ISO10126PaddingJDK112、192、256128ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128PKCS7Padding、ZeroBytePaddingBouncy Castle import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.math.BigInteger; import java.security.Key; import java.security.SecureRandom; public class Test { public static void main(String[] args) throws Exception { // 原始字符 String data = "Hello World!"; //生成key KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(new SecureRandom()); SecretKey secretKey = keyGenerator.generateKey(); byte[] key1 = secretKey.getEncoded(); //key转换为密钥 Key key2 = new SecretKeySpec(key1, "AES"); //加密 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5padding"); cipher.init(Cipher.ENCRYPT_MODE, key2); byte[] result = cipher.doFinal(data.getBytes()); BigInteger bigInteger = new BigInteger(1, result); System.out.println("jdkAES加密: " + bigInteger.toString(16)); //转换为十六进制 //解密 cipher.init(Cipher.DECRYPT_MODE, key2); result = cipher.doFinal(result); System.out.println("jdkAES解密: "+new String(result)); //转换字符串 } } 3.4 PBE

       基于口令的对称加密算法(它其实是对之前的算法的包装,比如说MD5和DES,我这里就是的是对MD5和DES包装的PBE算法,还有其他类型的PBE),口令就是我们俗话说的密码,PBE中有一个salt(盐)的概念,盐就是干扰码

import java.util.Base64; import javax.crypto.Cipher; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import java.security.Key; import java.security.SecureRandom; public class Test { public static void main(String[] args) throws Exception { // 原始字符 String data = "Hello World!"; //初始化盐 SecureRandom random=new SecureRandom(); byte[] salt = random.generateSeed(8); // 指定为8位的盐 (盐就是干扰码,通过添加干扰码增加安全) // 口令和密钥 String password = "TEST"; // 口令 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(data.getBytes()); System.out.println("jdk PBE加密: "+ Base64.getEncoder().encodeToString(result)); //解密 cipher.init(Cipher.DECRYPT_MODE, key, pbeParameterSpec); result = cipher.doFinal(result); System.out.println("jdk PBE解密: "+ new String(result)); } } 四、非对称加密

非对称算法就是发送方和接收方的密钥是不一样的,非对称相对于对称来说,有公钥和私钥的概念,基本上公钥是公开的,比如会在网络上传输,而私钥安全性要求就要高很多了,因为私钥是要保密的 基本的非对称算法有DH,RSA,ELGamal算法

4.1 DH

基于交换交换的非对称算法,发送方需要得到接收方的key构建本地密钥,而接收方也需要得到发送方的key构建自己本地的密钥。

import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import java.security.*; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; import java.util.Objects; public class Test { public static void main(String[] args) throws Exception { // 原始字符 String data = "Hello World!"; //初始化发送方密钥 KeyPairGenerator senderKeyPairGenerator=KeyPairGenerator.getInstance("DH"); senderKeyPairGenerator.initialize(512); //密钥长度 KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair(); byte[] senderPublicKeyEnc = senderKeyPair.getPublic().getEncoded(); //发送方key,需传递给接收方(网络,文件) //初始化接收方密钥 KeyFactory factory=KeyFactory.getInstance("DH"); X509EncodedKeySpec x509EncodedKeySpec=new X509EncodedKeySpec(senderPublicKeyEnc); //根据从发送方得到的key解析 PublicKey receiverPublicKey=factory.generatePublic(x509EncodedKeySpec); DHParameterSpec dhParameterSpec=((DHPublicKey)receiverPublicKey).getParams(); KeyPairGenerator receiverKeyPairGenerator=KeyPairGenerator.getInstance("DH"); receiverKeyPairGenerator.initialize(dhParameterSpec); KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair(); PrivateKey receiverPrivateKey = receiverKeyPair.getPrivate(); byte[] receiverPublicKeyEnc = receiverKeyPair.getPublic().getEncoded(); //密钥构建 KeyAgreement receiverKeyAgreement=KeyAgreement.getInstance("DH"); receiverKeyAgreement.init(receiverPrivateKey); receiverKeyAgreement.doPhase(receiverPublicKey, true); SecretKey receiverDESKey=receiverKeyAgreement.generateSecret("DES"); //发送发密钥(公钥) KeyFactory senderKeyFactory=KeyFactory.getInstance("DH"); x509EncodedKeySpec=new X509EncodedKeySpec(receiverPublicKeyEnc); PublicKey senderPublicKey=senderKeyFactory.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("双方密钥相同"); } //加密 Cipher cipher=Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, senderDESKey); byte[] result = cipher.doFinal(data.getBytes()); String encode = Base64.getEncoder().encodeToString(result); System.out.println("jdk DH加密: "+ encode); //解密 cipher.init(Cipher.DECRYPT_MODE, receiverDESKey); result=cipher.doFinal(result); System.out.println("jdk DH解密: " + new String(result)); } } 4.2 RSA

RSA相较于DH算法的实现简单,适用范围较广,公钥和私钥的创建较简单,而且支持公钥加密,私钥解密或者是私钥加密,公钥解密两种方式。

import javax.crypto.Cipher; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; public class Test { public static void main(String[] args) throws Exception { // 原始字符 String data = "Hello World!"; 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("public key:"+ Base64.getEncoder().encodeToString(rsaPublicKey.getEncoded())); System.out.println("private key:" + Base64.getEncoder().encodeToString(rsaPrivateKey.getEncoded())); //私钥加密,公钥解密--加密 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(data.getBytes()); System.out.println("RSA私钥加密,公钥解密--加密:"+Base64.getEncoder().encodeToString(result)); //私钥加密,公钥解密--解密 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("RSA私钥加密,公钥解密--解密:"+new String(result)); //公钥加密,私钥解密--加密 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(data.getBytes()); System.out.println("RSA公钥加密,私钥解密--加密:"+Base64.getEncoder().encodeToString(result)); //公钥加密,私钥解密--解密 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("RSA公钥加密,私钥解密--解密:"+new String(result)); } } 五、keyGenerator,KeyPairGenerator,SecretKeyFactory的区别

Java加密的常用的加密算法类型有三种:

【1】单向加密:也就是不可逆的加密,例如MD5,SHA,HMAC【2】对称加密:也就是加密方和解密方利用同一个秘钥对数据进行加密和解密,例如DES,PBE等等【3】非对称加密:非对称加密分为公钥和秘钥,二者是非对称的,例如用私钥加密的内容需要使用公钥来>解密,使用公钥加密的内容需要用私钥来解密,DSA,RSA…

而keyGenerator,KeyPairGenerator,SecretKeyFactory的三种使用方法刚好和这三种加密算法类型对上:

【1】keyGenerator:秘钥生成器,也就是更具算法类型随机生成一个秘钥,例如HMAC,所以这个大部分用在非可逆的算法中【2】SecretKeyFactory:秘密秘钥工厂,言外之意就是需要根据一个秘密(password)去生成一个秘钥,例如DES,PBE,所以大部分使用在对称加密中【3】KeyPairGenerator:秘钥对生成器,也就是可以生成一对秘钥,也就是公钥和私钥,所以大部分使用在非对称加密中


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有