java中常用的加密算法及描述,java加密的几种方法
00-1010序密钥分类密钥和密钥管理密钥生成信息抽象算法MD系列SHA系列对称加密算法DES3DESAES非对称加密算法
以下是00-1010编程中常见的加密算法,它们适用于不同的场景。除了信息摘要算法,其他加密方法也需要密钥。
信息算法对称加密算法非对称加密算法
00-1010密钥(也称为金钥)是指一些用于完成加密,解密和完整性验证.等密码应用的秘密信息
00-1010加密和解密中的密钥:对称加密中共享同一个密钥,非对称加密中划分公钥和私钥,加密用公钥,解密用私钥。键入消息认证码和数字签名:在消息认证码中,消息的发送方和接收方使用共享密钥进行身份验证。在数字签名中,签名使用私钥,而验证使用公钥。会话密钥和主密钥:每次通信只使用一次的密钥称为会话密钥。与会话密钥相比,重复使用的密钥称为主密钥。
00-1010密码一般由用户生成,可读,可以记忆存储,常用于软件管理,而密钥是实现加密算法的软件使用的,所以不需要可读(虽然编程中为了方便阅读是Base64)。我们也可以通过密码生成密钥。
00-1010密钥生成:可以用随机数或密码生成密钥。分发密钥:可以采用预先共享密钥、使用密钥分发中心、使用公钥密码、使用Diffie-Hellman密钥交换。更新密钥、保存密钥、无效密钥
目录
jdk的jdk (Java Cryptography Extension)包含了所有与加密相关的API。生成对称加密算法的密钥
public static secret key generate key(int keySize){ key generator key generator;请尝试{ key generator=key generator . getinstance( AES );key generator . init(key size);返回key generator . generate key();} catch(nosuch algorithm exception e){//忽略返回null} }生成对称非对称加密算法的密钥
/* * *生成非对称密钥对* * @ param keySize key size * @ param random指定随机源,使用默认的JCA util . getsecurerandom()* @ return非对称密钥对* @ throws nosuchalgorithm异常nosuch algorithm */public static ppkeys genkeys RSA(intkeysize,SecureRandom)throws nosuch algorithm exception { key pair generator=key pair generator . getinstance( RSA));if (null!=random){ generator . initialize(key size,random);} else { generator . initialize(keySize);} key pair pair=generator . generatekeypair();PP keys keys=new PP keys();public key public key=pair . get public();private key private key=pair . get private();keys . setpublickey(base64 . get encoder()。编码字符串(公共
cKey.getEncoded())); keys.setPrivateKey(Base64.getEncoder().encodeToString(privateKey.getEncoded())); return keys; }密钥协商(Diffie-Hellman)
密钥协商是一种协议,两方或多方在通过该协议建立相同的共享密钥,然后通讯内容进行对称加密传输,而不需要交换密钥。
大致过程:每一方生成一个公私钥对并将公钥分发给其它方,当都获得其他方的公钥副本后就可以离线计算共享密钥。
Java中提供了KeyAgreement
可以实现密钥协商。
Alice 和 Bob 分别用他们的私钥初始化自己的密钥协商对象KeyAgreement
,调用init()
方法;然后将通信的每一方的公钥 传入执行doPhase(Key key, boolean lastPhase)
;各方生成共享密钥generateSecret()
。
public static void diffieHellman() throws Exception { AlgorithmParameterGenerator dhParams = AlgorithmParameterGenerator.getInstance("DH"); dhParams.init(1024); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH"); keyGen.initialize(dhParams.generateParameters().getParameterSpec(DHParameterSpec.class), new SecureRandom()); KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH"); KeyPair alicePair = keyGen.generateKeyPair(); KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH"); KeyPair bobPair = keyGen.generateKeyPair(); aliceKeyAgree.init(alicePair.getPrivate()); bobKeyAgree.init(bobPair.getPrivate()); aliceKeyAgree.doPhase(bobPair.getPublic(), true); bobKeyAgree.doPhase(alicePair.getPublic(), true); boolean agree = Base64.getEncoder().encodeToString(aliceKeyAgree.generateSecret()).equals( Base64.getEncoder().encodeToString(bobKeyAgree.generateSecret()) ); System.out.println(agree); }
信息摘要算法
信息摘要算法又叫加密散列算法,加密过程不需要密钥,常见的加密散列算法有MD系列和SHA系列。一个理想的加密散列函数应该具备以下特性:
任何信息传入后,输出的总是长度固定;消息摘要看起来是随机的,这样根据原始信息就很难推测出值;好的散列函数碰撞概率应该极低,也就是不同信息传入后得到相同值的概率;
MD系列
MD5信息摘要算法(MD5 Message-Digest Algorithm),一种被广泛使用的加密散列函数,输出出一个128位(16字节)的散列值(hash value),MD5最初设计为加密散列函数,而目前发现它存在大量漏洞,所以不建议直接用作加密,不过在非加密场景下如:数据完整性校验,文件完整性校验它仍然有广泛的应用。
public static String md5(String content) { try { MessageDigest digest = MessageDigest.getInstance("MD5"); byte[] bytes = digest.digest(content.getBytes(StandardCharsets.UTF_8)); return Hex.encodeHexString(bytes); } catch (final NoSuchAlgorithmException e) { throw new IllegalArgumentException(e); } }
SHA系列
安全散列算法(Secure Hash Algorithm,缩写为SHA)是一个加密散列函数家族,是FIPS(美国联邦信息处理标准)所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的机率很高。 它们分别包含SHA-0、SHA-1、SHA-2、SHA-3
,其中SHA-0、SHA-1
输出长度是160位,SHA-2
包含SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256
,我们平时常用SHA-256
。
public static String sha256(String content) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256); byte[] bytes = digest.digest(content.getBytes(StandardCharsets.UTF_8)); return Hex.encodeHexString(bytes); } catch (final NoSuchAlgorithmException e) { throw new IllegalArgumentException(e); } }
对称加密算法
对称加密算法,双方持有相同密钥进行加解密,常见的对称加密算法:DES
3DES
AES128
AES192
AES256
。理解对称加密需要先明白下面几个概念:分组密码模式:将明文切割进行加密,再将密文拼接到一起。比如AES中会将明文数据切割为大小16字节的数据块,最后一块不够16字节时,使用Padding模式进行补充。填充(Padding):它有三种模式PKCS5、PKCS7和NOPADDING,PKCS5用缺少的字节数来填充,比如缺少5个字节就填充5个数字5,PKCS7缺少的字节数用0来填充。如果数据刚好是16的整数倍,PKCS5和PKCS7会再补充一个16字节数据来区分填充和有效数据,NOPADDING模式不需要填充。初始化向量:初始向量IV的作用是使加密更加安全可靠,在分组密码模式下IV大小对应数据块长度。加密模式:四种加密模式分别是:ECB(电子密码本模式)、CBC(密码分组链接模式)、CFB、OFB。ECB模式是仅仅使用明文和密钥来加密数据,所以该模式下不需要Padding,安全性也较弱,CBC模式数据分块并且使用传入IV依次进行异或操作,安全性也相对较高,所以目前一般都选择CBC模式。加密密钥:不同加密算法密钥长度不同,比如:DES 默认长度56位,3DES默认长度168位,也支持128位,AES默认128位,也支持192位,256位。我们一般根据密码生成密钥,密码长度需要满足算法密钥长度。
DES
DES
是对称加密算法领域中的典型算法,因为密钥默认长度为56 bit
,所以密码长度需要大于8 byte
,DESKeySpec
取前8 byte
进行密钥制作。
public static String encryptDES(byte[] content, String password) { try { SecureRandom random = new SecureRandom(); DESKeySpec desKeySpec = new DESKeySpec(password.getBytes()); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey, random); return Base64.getEncoder().encodeToString(cipher.doFinal(content)); } catch (Exception e) { throw new RuntimeException(e); } } public static String decryptDES(String content, String password) throws Exception { SecureRandom random = new SecureRandom(); DESKeySpec desKeySpec = new DESKeySpec(password.getBytes()); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = keyFactory.generateSecret(desKeySpec); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, secretKey, random); return new String(cipher.doFinal(Base64.getDecoder().decode(content))); }
3DES
3DES(即Triple DES)。是DES算法的加强,它使用3条56位的密钥对数据进行三次加密。它以DES为基本模块,通过组合分组方法设计出分组加密算法。比起最初的DES,3DES更为安全。密钥默认长度168 bit
, 密码需要大于24 byte
,IV 是8 byte
的随机数字和字母数组。
public static String encrypt3DESECB(String content, String key, String iv) { try { IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)); DESedeKeySpec dks = new DESedeKeySpec(key.getBytes(StandardCharsets.UTF_8)); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); SecretKey secretkey = keyFactory.generateSecret(dks); Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretkey, ivSpec); return Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes(StandardCharsets.UTF_8))); } catch (Exception e) { throw new RuntimeException(e); } } public static String decrypt3DESECB(String content, String key, String iv) { try { IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)); DESedeKeySpec dks = new DESedeKeySpec(key.getBytes(StandardCharsets.UTF_8)); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); SecretKey secretkey = keyFactory.generateSecret(dks); Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secretkey, ivSpec); return new String(cipher.doFinal(Base64.getDecoder().decode(content)), StandardCharsets.UTF_8); } catch (Exception e) { throw new RuntimeException(e); } }
AES
AES 高级数据加密标准,能够有效抵御已知的针对DES算法的所有攻击,默认密钥长度为128 bit
,还可以供选择192 bit
,256 bit
。AES-128
AES-192
AES-256
默认AES-128
,使用PBEKeySpec
生成固定大小的密钥。
public static String encryptAES128(String plainText, String password, String salt) throws Exception { SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); byte[] saltBytes = salt.getBytes(StandardCharsets.UTF_8); // AES-128 密钥长度为128bit PBEKeySpec spec = new PBEKeySpec( password.toCharArray(), saltBytes, 1000, 128 ); SecretKey secretKey = factory.generateSecret(spec); SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); AlgorithmParameters params = cipher.getParameters(); IvParameterSpec iv = params.getParameterSpec(IvParameterSpec.class); cipher.init(Cipher.ENCRYPT_MODE, secret, iv); byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8)); String encodedText = Base64.getEncoder().encodeToString(encryptedTextBytes); String encodedIV = Base64.getEncoder().encodeToString(iv.getIV()); String encodedSalt = Base64.getEncoder().encodeToString(saltBytes); return encodedSalt + "." + encodedIV + "." + encodedText; } public static String decryptAES128(String encryptedText, String password) throws Exception { String[] fields = encryptedText.split("\."); byte[] saltBytes = Base64.getDecoder().decode(fields[0]); byte[] ivBytes = Base64.getDecoder().decode(fields[1]); byte[] encryptedTextBytes = Base64.getDecoder().decode(fields[2]); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); PBEKeySpec spec = new PBEKeySpec( password.toCharArray(), saltBytes, 1000, 128 ); SecretKey secretKey = factory.generateSecret(spec); SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes)); byte[] decryptedTextBytes; try { decryptedTextBytes = cipher.doFinal(encryptedTextBytes); return new String(decryptedTextBytes); } catch (IllegalBlockSizeException BadPaddingException e) { throw new RuntimeException(e); } }使用
AES-256
时可能会出现下面异常:
java.security.InvalidKeyException: Illegal key sizeJDK 1.8.0_161 及以上版本默认已经启用无限强度加密:
static { java.security.Security.setProperty("crypto.policy", "unlimited"); }JDK 1.8.0_161以前版本需要手动安装 jce策略文件(下载地址)
非对称加密算法
非对称加密使用一对密钥,公钥用作加密,私钥则用作解密。关于密钥大小,截至2020年,公开已知的最大RSA密钥是破解的是829位的RSA-250,建议至少使用 2048 位密钥。
public static String encrypt(byte[] publicKey, String plainText) { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey); KeyFactory kf; try { kf = KeyFactory.getInstance("RSA"); PublicKey publicKeySecret = kf.generatePublic(keySpec); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, publicKeySecret); byte[] encryptedBytes = cipher.doFinal(plainText.getBytes()); return new String(Base64.getEncoder().encode(encryptedBytes)); } catch (Exception e) { log.error("Rsa encrypt error ", e); throw new RuntimeException(e); } } public static String decrypt(byte[] privateKey, String encryptedText) { PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey); KeyFactory kf; try { kf = KeyFactory.getInstance("RSA"); PrivateKey privateKeySecret = kf.generatePrivate(keySpec); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, privateKeySecret); return new String(cipher.doFinal(Base64.getDecoder().decode(encryptedText)), StandardCharsets.UTF_8); } catch (Exception e) { log.error("Rsa decrypt error ", e); throw new RuntimeException(e); } }到此这篇关于Java实现常用的三种加密算法详解的文章就介绍到这了,更多相关Java加密算法内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。