当前位置: 首页 > news >正文

JAVA中加密与解密

BASE64加密/解密

Base64 编码会将字符串编码得到一个含有 A-Za-z0-9+/ 的字符串。标准的 Base64 并不适合直接放在URL里传输,因为URL编码器会把标准 Base64 中的“/”和“+”字符变为形如 “%XX” 的形式,而这些 “%” 号在存入数据库时还需要再进行转换,因为 ANSI SQL 中已将“%”号用作通配符。

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;import java.nio.charset.StandardCharsets;public class Base64Util {/**** BASE64解密* @param key* @return* @throws Exception*/public static byte[] decryBASE64(String key) throws Exception {return (new BASE64Decoder()).decodeBuffer(key);}/**** BASE64加密* @param key* @return* @throws Exception*/public static String encryptBASE64(byte[] key) {return (new BASE64Encoder()).encode(key);}public static void main(String[] args) throws Exception {String base64 = encryptBASE64("DAIHAO".getBytes(StandardCharsets.UTF_8));System.out.println(base64);System.out.println(new String(decryBASE64(base64)));}
}

MD5(Message Digest Algorithm)加密

MD5是一种信息摘要算法(message-digest algorithm 5 ),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值,用来确保信息传输完整一致性。

  • 不可逆 知道密文和加密方式,无法反向计算出原密码 (但是有md5破解网站,专门查询MD5码)

撞库:原理是:通过建立大型的数据库,把日常的各种句子通过md5加密成为密文,不断积累更新大量句子,放在庞大的数据库里;然后,有人拿了别人的密文,想查询真实的密码,就需要把密文拿到这个数据库的网站(免费MD5加密解密:https://md5.cn/)去查询。

  • 长度固定 任意长度的数据,算出来的md5值长度都是固定的

  • 强抗碰撞 想找到两个不同的数据,使它们具有相同的MD5值,是非常困难的。

  • 容易计算 原理通俗易懂

  • 细微性(高度离散性)对原数据进行任何改动,都会有很大的变化

import java.security.MessageDigest;public class MD5Util {public static final String KEY_MD5 = "MD5";/**** MD5加密(生成唯一的MD5值)* @param data* @return* @throws Exceptionx	 */public static byte[] encryMD5(byte[] data) throws Exception {MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);md5.update(data);return md5.digest();}
}

DES(Data Encryption Standard)对称加密

DES 是一种对称加密算法,所谓对称加密算法就是:加密和解密使用相同密钥的算法。DES 加密算法出自 IBM 的研究,后来被美国政府正式采用,之后开始广泛流传。但近些年使用越来越少,因为 DES 使用 56 位密钥,以现代的计算能力,24 小时内即可被破解。

顺便说一下 3DES(Triple DES),它是 DES 向 AES 过渡的加密算法,使用 3 条 56 位的密钥对数据进行三次加密。是 DES 的一个更安全的变形。它以 DES 为基本模块,通过组合分组方法设计出分组加密算法。比起最初的 DES,3DES 更为安全。

使用 Java 实现 DES 加密解密,注意密码长度要是 8 的倍数。加密和解密的 Cipher 构造参数一定要相同,不然会报错。

数据加密标准算法,和BASE64最明显的区别就是有一个工作密钥,该密钥既用于加密、也用于解密,并且要求密钥是一个长度至少大于8位的字符串。

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
import java.security.SecureRandom;public class DesUtil {private static Key key;private static String KEY_STR="DAIAHO";private static String CHARSETNAME="UTF-8";private static String ALGORITHM="DES";static {try {//生成DES算法对象KeyGenerator generator=KeyGenerator.getInstance(ALGORITHM);//运用SHA1安全策略SecureRandom secureRandom=SecureRandom.getInstance("SHA1PRNG");//设置上密钥种子secureRandom.setSeed(KEY_STR.getBytes());//初始化基于SHA1的算法对象generator.init(secureRandom);//生成密钥对象key=generator.generateKey();generator=null;} catch (Exception e) {throw new RuntimeException(e);}}/**** 获取加密的信息* @param str* @return*/public static String getEncryptString(String str) {//基于BASE64编码,接收byte[]并转换成StringBASE64Encoder encoder = new BASE64Encoder();try {//按utf8编码byte[] bytes = str.getBytes(CHARSETNAME);//获取加密对象Cipher cipher = Cipher.getInstance(ALGORITHM);//初始化密码信息cipher.init(Cipher.ENCRYPT_MODE, key);//加密byte[] doFinal = cipher.doFinal(bytes);//byte[]to encode好的String 并返回return encoder.encode(doFinal);} catch (Exception e) {throw new RuntimeException(e);}}/**** 获取解密之后的信息* @param str* @return*/public static String getDecryptString(String str) {BASE64Decoder decoder = new BASE64Decoder();try {//将字符串decode成byte[]byte[] bytes = decoder.decodeBuffer(str);//获取解密对象Cipher cipher = Cipher.getInstance(ALGORITHM);//初始化解密信息cipher.init(Cipher.DECRYPT_MODE, key);//解密byte[] doFial = cipher.doFinal(bytes);return new String(doFial, CHARSETNAME);} catch (Exception e) {throw new RuntimeException(e);}}public static void main(String[] args) {String daiaho = getEncryptString("DAIAHO");System.out.println(daiaho);String decryptString = getDecryptString(daiaho);System.out.println(decryptString);}
}

AES(Advanced Encryption Standard)加密/解密

AES加密/解密算法是一种可逆的对称加密算法,这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥,一般用于服务端对服务端之间对数据进行加密/解密。它是一种为了替代原先DES、3DES而建立的高级加密标准(Advanced Encryption Standard)。

作为可逆且对称的块加密,AES加密算法的速度比公钥加密等加密算法快很多,在很多场合都需要AES对称加密,但是要求加密端和解密端双方都使用相同的密钥是AES算法的主要缺点之一。

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;public class AESUtil {public static final String algorithm = "AES";public static final String transformation = "AES/CBC/PKCS5Padding";public static final String key = "DAIHAODAIHAO9527";/**** 加密* @param original 需要加密的参数(注意必须是16位)* @return* @throws Exception*/public static String encryptByAES(String original) throws Exception {// 获取CipherCipher cipher = Cipher.getInstance(transformation);// 生成密钥SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);// 指定模式(加密)和密钥// 创建初始化向量IvParameterSpec iv = new IvParameterSpec(key.getBytes());cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);// 加密byte[] bytes = cipher.doFinal(original.getBytes());return Base64Util.encryptBASE64(bytes);}/*** 解密* @param encrypted 需要解密的参数* @return* @throws Exception*/public static String decryptByAES(String encrypted) throws Exception {// 获取CipherCipher cipher = Cipher.getInstance(transformation);// 生成密钥SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);// 指定模式(解密)和密钥// 创建初始化向量IvParameterSpec iv = new IvParameterSpec(key.getBytes());cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);// 解密byte[] bytes = cipher.doFinal(Base64Util.decryBASE64(encrypted));return new String(bytes);}public static void main(String[] args) throws Exception {String s = encryptByAES("DAIHAO");System.out.println(s);System.out.println(decryptByAES(s));}
}

HMAC (Hash Message Authentication Code)散列消息鉴别码

使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;public class HMACUtil {public static final String KEY_MAC = "HmacMD5";/**** 初始化HMAC密钥* @return* @throws Exception*/public static String initMacKey() throws Exception {KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);SecretKey secreKey = keyGenerator.generateKey();return Base64Util.encryptBASE64(secreKey.getEncoded());}/*** HMAC加密** @param data* @param key* @return* @throws Exception*/public static byte[] encryHMAC(byte[] data, String key) throws Exception {SecretKey secreKey = new SecretKeySpec(Base64Util.decryBASE64(key), KEY_MAC);Mac mac = Mac.getInstance(secreKey.getAlgorithm());mac.init(secreKey);return mac.doFinal();}public static void main(String[] args) throws Exception {String key = initMacKey();byte[] daiahos = encryHMAC("DAIHAO".getBytes(StandardCharsets.UTF_8), key);for (byte daiaho : daiahos) {System.out.println(daiaho);}}
}

恺撒加密

恺撒密码的替换方法是通过排列明文和密文字母表,密文字母表示通过将明文字母表向左或向右移动一个固定数目的位置。例如,当偏移量是左移3的时候(解密时的密钥就是3):

明文字母表:ABCDEFGHIJKLMNOPQRSTUVWXYZ ;
密文字母表:DEFGHIJKLMNOPQRSTUVWXYZABC。

使用时,加密者查找明文字母表中需要加密的消息中的每一个字母所在位置,并且写下密文字母表中对应的字母。需要解密的人则根据事先已知的密钥反过来操作,得到原来的明文。例如:

明文:THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG ;
密文:WKH TXLFN EURZQ IRA MXPSV RYHU WKH ODCB GRJ。

public class KaisaUtil {/**** 使用凯撒加密方式加密数据* @param orignal 原文* @param key 密钥* @return 加密后的字符*/private static String encryptKaisa(String orignal, int key) {//将字符串转换为数组char[] chars = orignal.toCharArray();StringBuffer buffer = new StringBuffer();//遍历数组for(char aChar : chars) {//获取字符的ASCII编码int asciiCode = aChar;//偏移数据asciiCode += key;//将偏移后的数据转为字符char result = (char)asciiCode;//拼接数据buffer.append(result);}return buffer.toString();}/*** 使用凯撒加密方式解密数据** @param encryptedData :密文* @param key           :密钥* @return : 源数据*/private static String decryptKaiser(String encryptedData, int key) {// 将字符串转为字符数组char[] chars = encryptedData.toCharArray();StringBuilder sb = new StringBuilder();// 遍历数组for (char aChar : chars) {// 获取字符的ASCII编码int asciiCode = aChar;// 偏移数据asciiCode -= key;// 将偏移后的数据转为字符char result = (char) asciiCode;// 拼接数据sb.append(result);}return sb.toString();}public static void main(String[] args) {String encode = encryptKaisa( "DAIHAO", 3);System.out.println(encode);System.out.println(decryptKaiser(encode, 3));}}

SHA(Secure Hash Algorithm)安全散列算法

SHA-1是一种数据加密算法,该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。

单向散列函数的安全性在于其产生散列值的操作过程具有较强的单向性。如果在输入序列中嵌入密码,那么任何人在不知道密码的情况下都不能产生正确的散列值,从而保证了其安全性。SHA将输入流按照每块512位(64个字节)进行分块,并产生20个字节的被称为信息认证代码或信息摘要的输出。

该算法输入报文的长度不限,产生的输出是一个160位的报文摘要。输入是按512 位的分组进行处理的。SHA-1是不可逆的、防冲突,并具有良好的雪崩效应。

通过散列算法可实现数字签名实现,数字签名的原理是将要传送的明文通过一种函数运算(Hash)转换成报文摘要(不同的明文对应不同的报文摘要),报文摘要加密后与明文一起传送给接受方,接受方将接受的明文产生新的报文摘要与发送方的发来报文摘要解密比较,比较结果一致表示明文未被改动,如果不一致表示明文已被篡改。

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class SHAUtil {public static final String KEY_SHA = "SHA";public static final String ALGORITHM = "SHA-256";/**** SHA加密(比MD5更安全)* @param data* @return* @throws Exception*/public static byte[] encryptSHA(byte[] data) throws Exception{MessageDigest sha = MessageDigest.getInstance(KEY_SHA);sha.update(data);return sha.digest();}public static String SHAEncrypt(final String content) {try {MessageDigest sha = MessageDigest.getInstance(KEY_SHA);byte[] sha_byte = sha.digest(content.getBytes());StringBuffer hexValue = new StringBuffer();for (byte b : sha_byte) {//将其中的每个字节转成十六进制字符串:byte类型的数据最高位是符号位,通过和0xff进行与操作,转换为int类型的正整数。String toHexString = Integer.toHexString(b & 0xff);hexValue.append(toHexString.length() == 1 ? "0" + toHexString : toHexString);}return hexValue.toString();} catch (Exception e) {e.printStackTrace();}return "";}//SHA-256加密public static String SHA256Encrypt(String sourceStr) {MessageDigest md = null;try {md = MessageDigest.getInstance(ALGORITHM);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}if (null != md) {md.update(sourceStr.getBytes());String digestStr = getDigestStr(md.digest());return digestStr;}return null;}private static String getDigestStr(byte[] origBytes) {String tempStr = null;StringBuilder stb = new StringBuilder();for (int i = 0; i < origBytes.length; i++) {tempStr = Integer.toHexString(origBytes[i] & 0xff);if (tempStr.length() == 1) {stb.append("0");}stb.append(tempStr);}return stb.toString();}public static void main(String[] args) {System.out.println(SHAEncrypt("DAIHAO"));System.out.println(SHA256Encrypt("DAIHAO"));}
}

RSA加密/解密

RSA算法是非对称密码算法。非对称密码又称为公钥密码,意思为每对加密包含一个公钥(可能为他人所知)和一个私钥(可能不为所有人所知)。有效的安全需要保持私钥的私密性;公钥可以在不影响安全性的情况下公开分发。

RSA 的安全性依赖于分解两个大素数乘积的实际困难,但相对较慢,可以称为“分解问题”。

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;import javax.crypto.Cipher;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;public class RSAUtil {private static String PUBLICKEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhX8nefMfPt7jY4wVr71XbDlwYc1D3ThS\n" +"fBJwUqzu1ZI9C5HHMUfQeA140fhdf3OaeCR41W4yMRrFKL1sasBs1nN/S5714CGqLICxTJq1bxlS\n" +"2cgvf/yW1y64U/2QaBolSIl1o/ltywD3Ztaarl3qBzjt1f5p7NYTtyO3lT97PHnY5H8WVCAbR5yu\n" +"zXRBj9lYFjaeUYWEhM/sd9OJeTfevnqzgVKXRq2jcAqKnI4RmdiJ4w5qacuN/TB8o6pRR6XVU/vx\n" +"jsDBta4AEe3ZWwgtS+RXMuEkjX7tddzwxVgyGhVRAj4yWWXxQu57i2Kq4MHdJ07IiyaarFpzo0CY\n" +"SwzJQwIDAQAB";private static String PRIVATEKEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCFfyd58x8+3uNjjBWvvVdsOXBh\n" +"zUPdOFJ8EnBSrO7Vkj0LkccxR9B4DXjR+F1/c5p4JHjVbjIxGsUovWxqwGzWc39LnvXgIaosgLFM\n" +"mrVvGVLZyC9//JbXLrhT/ZBoGiVIiXWj+W3LAPdm1pquXeoHOO3V/mns1hO3I7eVP3s8edjkfxZU\n" +"IBtHnK7NdEGP2VgWNp5RhYSEz+x304l5N96+erOBUpdGraNwCoqcjhGZ2InjDmppy439MHyjqlFH\n" +"pdVT+/GOwMG1rgAR7dlbCC1L5Fcy4SSNfu113PDFWDIaFVECPjJZZfFC7nuLYqrgwd0nTsiLJpqs\n" +"WnOjQJhLDMlDAgMBAAECggEAO8qEutkKkJUx0T9H40txoXZkgFl4YNe+EfYMOutbmWqDTvA/ADKD\n" +"C5I1IA4WimQTtmXXfPh7IIU18xZMPc/rr21RgWQ0CevqFT6aqo3MX3M/KW3A4JkYUk6Jnoy+JfI3\n" +"6rIub3/jDf5j0Lqj0x8bF5sG40as2LfVYrxrmDwzjRT15KyuX6k8ZLNxS/kyVKCReY4ZEipx4UrD\n" +"RBi4avIPFuKFHL5dg76bR7dUuVM9mjBxpEi4VglgZ9RoC+zFEF0qPeefgC8GI7dM/w8ium+SVVvd\n" +"NAKccYQi+UVmMx8irawwVHNySY5BThNHVnANh1y6udhKJ6VH8YvsqKnBjSWjiQKBgQD0KDamwoYh\n" +"dGuZVKQzT+8Dws443nqlWS07GkVjrmtsQWM/rg/olrdiNdjDtu4mK07pJlrd1WltwDzeN22mChUZ\n" +"mxcwn0UCJUU5oROSiU3NXSVVQtNCuJlXejEIpOI36I+qxKPMoNXG8toP7EEVedettnt0RQe6Qgcg\n" +"hZiYRX+m3wKBgQCL+NSvRF4wpf1xv+xETn1fKlwaMtkow55B6mOS6KpUJbTSZeg2eGNQ5ZvVmHdv\n" +"eG1jrkgc+32RgppCnAX1ohGu2Ut601xmkqxKTAMe9RUCgmF055ZcGtrjnh9LusrSMtuL8tzJgLTX\n" +"EF1apLoYcBQpKAKbqMqAGyvFbmDOIs9eHQKBgQDwkcb3nOeIgyuZ0tpPbM02yXVkd2IlFa8JcyM3\n" +"yp4x9mOSVTF7nTVn4WKJxO72UOnZtF8IAMV2zFmtIrQ5S+nqZvP8hpH6QTrqQ5oDYqJ0XPjx/3wl\n" +"W7pLhSxXNg9nww/71PEIKNk6xAK0ebbPMFSg5xLRR0sL7Q8Urk3ii2fxxQKBgDjlnQ7hq6f60Vs7\n" +"uL7LaQsWHPpJURzQ57PDo1ZEXXh3G1mrMwlxRm3L59ybbXFScqTiY03krNZJUItjAMkoaCe7DIOR\n" +"By5q0L4ix+H9ndy3QwZSXTxzbia4T+BovalUIwpwXm9Kcjg53rjJ3Rux84AHU4gSxL3uTYyjoZYp\n" +"cEHBAoGBAKsOCaiwHqnv1EHBhax3WAUgtcrS0DYANmRXBoaNBm0ijtaaDDOn+9km+LrA2JahbQhm\n" +"Rlsl2LTutHfMC1h00lkfwR/1g9MlKYYZWHVff8tGurPYvZhCfDf6Je1ssvhqU5t8IPAQGmAxVRLI\n" +"S4RHO29DU7Tpxn1fIcDt33m6bSzg";/*** RSA+BASE64加密(先RSA加密,然后Base64加密)** @param secretContent:secretContent要加密的内容*/public static String encrypt(String secretContent) {String byte2Base64 = "";try {//将Base64编码后的公钥转换成PublicKey对象PublicKey publicKey = string2PublicKey(RSAUtil.PUBLICKEY);//用公钥加密byte[] publicEncrypt = publicEncrypt(secretContent.getBytes(), publicKey);//加密后的内容Base64编码byte2Base64 = byte2Base64(publicEncrypt);} catch (Exception e) {e.printStackTrace();}return byte2Base64;}/*** BASE64+RAS解密(先Base64解密,然后RSA解密)** @param decodeContent :解密字符串*/public static String decode(String decodeContent) {byte[] privateDecrypt = new byte[]{};try {//将Base64编码后的私钥转换成PrivateKey对象PrivateKey privateKey = string2PrivateKey(PRIVATEKEY);//加密后的内容Base64解码byte[] base642Byte = base642Byte(decodeContent);//用私钥解密privateDecrypt = privateDecrypt(base642Byte, privateKey);} catch (Exception e) {e.printStackTrace();}return new String(privateDecrypt);}//生成秘钥对public static KeyPair getKeyPair() throws Exception {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);KeyPair keyPair = keyPairGenerator.generateKeyPair();return keyPair;}//获取公钥(Base64编码)public static String getPublicKey(KeyPair keyPair) {PublicKey publicKey = keyPair.getPublic();byte[] bytes = publicKey.getEncoded();return byte2Base64(bytes);}//获取私钥(Base64编码)public static String getPrivateKey(KeyPair keyPair) {PrivateKey privateKey = keyPair.getPrivate();byte[] bytes = privateKey.getEncoded();return byte2Base64(bytes);}//将Base64编码后的公钥转换成PublicKey对象public static PublicKey string2PublicKey(String pubStr) throws Exception {byte[] keyBytes = base642Byte(pubStr);X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PublicKey publicKey = keyFactory.generatePublic(keySpec);return publicKey;}//将Base64编码后的私钥转换成PrivateKey对象public static PrivateKey string2PrivateKey(String priStr) throws Exception {byte[] keyBytes = base642Byte(priStr);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PrivateKey privateKey = keyFactory.generatePrivate(keySpec);return privateKey;}//公钥加密public static byte[] publicEncrypt(byte[] content, PublicKey publicKey) throws Exception {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] bytes = cipher.doFinal(content);return bytes;}//私钥解密public static byte[] privateDecrypt(byte[] content, PrivateKey privateKey) throws Exception {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] bytes = cipher.doFinal(content);return bytes;}//字节数组转Base64编码public static String byte2Base64(byte[] bytes) {BASE64Encoder encoder = new BASE64Encoder();return encoder.encode(bytes);}//Base64编码转字节数组public static byte[] base642Byte(String base64Key) throws IOException {BASE64Decoder decoder = new BASE64Decoder();return decoder.decodeBuffer(base64Key);}public static void main(String[] args) throws Exception {String daihao = encrypt("DAIHAO");System.out.println(daihao);System.out.println(decode(daihao));}}

PBE加密/解密

PBE算法在加密过程中并不是直接使用口令来加密,而是加密的密钥由口令生成,这个功能由PBE算法中的KDF函数完成。

KDF函数的实现过程为:将用户输入的口令首先通过“盐”(salt)的扰乱产生准密钥,再将准密钥经过散列函数多次迭代后生成最终加密密钥,密钥生成后,PBE算法再选用对称加密算法对数据进行加密,可以选择DES、3DES、RC5等对称加密算法。

口令:一般与用户名对应,是某个用户自己编织的便于 记忆的一串单词、数字、汉字字符,口令的特点容易被记忆, 也容易泄露和被盗取,容易被社会工程学、暴力破解、撞库等方式获取。

密钥:是经过加密算法计算出来的,密钥一般不容易记忆,不容易被破解,而且很多时候密钥是作为算法的参数出现的,算法对于密钥长度也是有要求的,因为加密算法的作用就是利用密钥来扰乱明文顺序。

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 PBEUtil {public static final String ALGORITHM = "PBEWITHMD5andDES";public static final int ITERATION_COUNT = 100;public static byte[] initSalt() throws Exception {//实例化安全随机数SecureRandom random = new SecureRandom();return random.generateSeed(8);}/**** 转换密钥* @param password 密码* @return 密钥* @throws Exception*/private static Key toKey(String password) throws Exception {//密钥材料PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());//实例化SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);//生成密钥return factory.generateSecret(keySpec);}/**** 加密* @param data 待加密数据* @param password 密钥* @param salt* @return* @throws Exception*/public static byte[] encrypt(byte[] data, String password, byte[] salt) throws Exception {//转换密钥Key key = toKey(password);//实例化PBE参数材料PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATION_COUNT);//实例化Cipher cipher = Cipher.getInstance(ALGORITHM);//初始化cipher.init(Cipher.ENCRYPT_MODE, key, spec);return cipher.doFinal(data);}/**** 解密* @param data 待解密数据* @param password 密钥* @param salt* @return* @throws Exception*/public static byte[] decrypt(byte[] data, String password, byte[] salt) throws Exception {//转换密钥Key key = toKey(password);//实例化PBE参数材料PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATION_COUNT);//实例化Cipher cipher = Cipher.getInstance(ALGORITHM);//初始化cipher.init(Cipher.DECRYPT_MODE, key, spec);//执行操作return cipher.doFinal(data);}private static String showByteArray(byte[] data) {if (null == data) {return null;}StringBuilder sb = new StringBuilder();for (byte b : data) {sb.append(b).append(",");}sb.deleteCharAt(sb.length() - 1);sb.append("");return sb.toString();}public static void main(String[] args) throws Exception {byte[] salt = initSalt();System.out.println("salt:" + showByteArray(salt));String password = "DAIHAO";System.out.println("口令:" + password);String data = "DAIHAO";byte[] encryptData = encrypt(data.getBytes(), password, salt);System.out.println("加密后数据:" + showByteArray(encryptData));byte[] decryptData = decrypt(encryptData, password, salt);System.out.println("解密后数据:" + new String(decryptData));}
}

安全级别

在这里插入图片描述

相关文章:

JAVA中加密与解密

BASE64加密/解密 Base64 编码会将字符串编码得到一个含有 A-Za-z0-9/ 的字符串。标准的 Base64 并不适合直接放在URL里传输&#xff0c;因为URL编码器会把标准 Base64 中的“/”和“”字符变为形如 “%XX” 的形式&#xff0c;而这些 “%” 号在存入数据库时还需要再进行转换&…...

改进YOLO系列 | ICLR2022 | OMNI-DIMENSIONAL DYNAMIC CONVOLUTION: 全维动态卷积

单个静态卷积核是现代卷积神经网络(CNNs)的常见训练范式。然而,最近的动态卷积研究表明,学习加权为其输入依赖注意力的n个卷积核的线性组合可以显著提高轻量级CNNs的准确性,同时保持高效的推理。然而,我们观察到现有的作品通过卷积核空间的一个维度(关于卷积核数量)赋予…...

信息收集之Github搜索语法

信息收集之Github搜索语法1.Github的搜索语法2.使用 Github 进行邮件配置信息收集3.使用Github进行数据库信息收集4.使用Github进行 SVN 信息收集5.使用Github进行综合信息收集在测试的信息收集阶段&#xff0c;可以去Github和码云上搜索与目标有关的信息&#xff0c;或者就有意…...

【案例教程】拉格朗日粒子扩散模式FLEXPART

拉格朗日粒子扩散模式FLEXPART通过计算点、线、面或体积源释放的大量粒子的轨迹&#xff0c;来描述示踪物在大气中长距离、中尺度的传输、扩散、干湿沉降和辐射衰减等过程。该模式既可以通过时间的前向运算来模拟示踪物由源区向周围的扩散&#xff0c;也可以通过后向运算来确定…...

试题 算法训练 自行车停放

问题描述 有n辆自行车依次来到停车棚&#xff0c;除了第一辆自行车外&#xff0c;每辆自行车都会恰好停放在已经在停车棚里的某辆自行车的左边或右边。(e.g.停车棚里已经有3辆自行车&#xff0c;从左到右编号为&#xff1a;3,5,1。现在编号为2的第4辆自行车要停在5号自行车的左…...

泛型与Map接口

Java学习之道 泛型 泛型这种参数类型可以用在类、方法和接口中&#xff0c;分别被称为泛型类&#xff0c;泛型方法&#xff0c;泛型接口 参数化类型&#xff1a;将类型由原来的具体的类型参数化&#xff0c;在使用/调用时传入具体的类型JDK5引入特性提供了安全检测机制&#xf…...

Unity Bug记录本

//个人记录&#xff0c;持续更新 1、将此代码挂载到空脚本上&#xff1a; bool flag (object)GetComponent<Camera>() null; bool flag1 (object)GetComponent<Text>() null; Debug.Log(flag"::"flag1); //输出结果&#xff1a;False::True bool…...

B. The Number of Products)厉害

You are given a sequence a1,a2,…,ana1,a2,…,an consisting of nn non-zero integers (i.e. ai≠0ai≠0). You have to calculate two following values: the number of pairs of indices (l,r)(l,r) (l≤r)(l≤r) such that al⋅al1…ar−1⋅aral⋅al1…ar−1⋅ar is neg…...

一起Talk Android吧(第五百一十二回:自定义Dialog)

文章目录整体思路实现方法第一步第二步第三步第四步各位看官们大家好&#xff0c;上一回中咱们说的例子是"自定义Dialog主题",这一回中咱们说的例子是" 自定义Dialog"。闲话休提&#xff0c;言归正转&#xff0c; 让我们一起Talk Android吧&#xff01;整体…...

GinVueAdmin源码分析3-整合MySQL

目录文件结构数据库准备配置文件处理config.godb_list.gogorm_mysql.gosystem.go初始化数据库gorm.gogorm_mysql.go开始初始化测试数据库定义实体类 Userserviceapi开始测试&#xff01;文件结构 本文章将使用到上一节创建的 CommonService 接口&#xff0c;用于测试连接数据库…...

大数据框架之Hadoop:MapReduce(三)MapReduce框架原理——MapReduce开发总结

在编写MapReduce程序时&#xff0c;需要考虑如下几个方面&#xff1a; 1、输入数据接口&#xff1a;InputFormat 默认使用的实现类是&#xff1a;TextInputFormatTextInputFormat的功能逻辑是&#xff1a;一次读一行文本&#xff0c;然后将该行的起始偏移量作为key&#xff0…...

requests---(4)发送post请求完成登录

前段时间写过一个通过cookies完成登录&#xff0c;今天我们写一篇通过post发送请求完成登录豆瓣网 模拟登录 1、首先找到豆瓣网的登录接口 打开豆瓣网站的登录接口&#xff0c;请求错误的账号密码&#xff0c;通过F12或者抓包工具找到登录接口 通过F12抓包获取到请求登录接口…...

Python抓取数据具体流程

之前看了一段有关爬虫的网课深有启发&#xff0c;于是自己也尝试着如如何过去爬虫百科“python”词条等相关页面的整个过程记录下来&#xff0c;方便后期其他人一起来学习。 抓取策略 确定目标&#xff1a;重要的是先确定需要抓取的网站具体的那些部分&#xff0c;下面实例是…...

【Python学习笔记】第二十四节 Python 正则表达式

一、正则表达式简介正则表达式&#xff08;regular expression&#xff09;是一个特殊的字符序列&#xff0c;它能帮助你方便的检查一个字符串是否与某种模式匹配。正则表达式是对字符串&#xff08;包括普通字符&#xff08;例如&#xff0c;a 到 z 之间的字母&#xff09;和特…...

数字逻辑基础:原码、反码、补码

时间紧、不理解可以只看这里的结论 正数的原码、反码、补码相同。等于真值对应的机器码。 负数的原码等于机器码&#xff0c;反码为原码的符号位不变&#xff0c;其余各位按位取反。补码为反码1。 三种码的出现是为了解决计算问题并简化电路结构。 在原码和反码中&#xff0c;存…...

有限差分法-差商公式及其Matlab实现

2.1 有限差分法 有限差分法 (finite difference method)是一种数值求解偏微分方程的方法,它将偏微分方程中的连续变量离散化为有限个点上的函数值,然后利用差分逼近导数,从而得到一个差分方程组。通过求解差分方程组,可以得到原偏微分方程的数值解。 有限差分法是一种历史…...

高校就业信息管理系统

1引言 1.1编写目的 1.2背景 1.3定义 1.4参考资料 2程序系统的结构 3登录模块设计说明一 3.1程序描述 3.2功能 3.3性能 3.4输人项 3.5输出项 3.6算法 3.7流程逻辑 3.8接口 3.10注释设计 3.11限制条件 3.12测试计划 3.13尚未解决的问题 4注册模块设计说明 4.…...

【Java|golang】2373. 矩阵中的局部最大值

给你一个大小为 n x n 的整数矩阵 grid 。 生成一个大小为 (n - 2) x (n - 2) 的整数矩阵 maxLocal &#xff0c;并满足&#xff1a; maxLocal[i][j] 等于 grid 中以 i 1 行和 j 1 列为中心的 3 x 3 矩阵中的 最大值 。 换句话说&#xff0c;我们希望找出 grid 中每个 3 x …...

根据指定函数对DataFrame中各元素进行计算

【小白从小学Python、C、Java】【计算机等级考试500强双证书】【Python-数据分析】根据指定函数对DataFrame中各元素进行计算以下错误的一项是?import numpy as npimport pandas as pdmyDict{A:[1,2],B:[3,4]}myDfpd.DataFrame(myDict)print(【显示】myDf)print(myDf)print(【…...

【蓝桥杯集训·每日一题】AcWing 3502. 不同路径数

文章目录一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解三、知识风暴一、题目 1、原题链接 3502. 不同路径数 2、题目描述 给定一个 nm 的二维矩阵&#xff0c;其中的每个元素都是一个 [1,9] 之间的正整数。 从矩阵中的任意位置出发&#xf…...

Java - 数据结构,二叉树

一、什么是树 概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。它具有以下的特点&#xff1a; 1、有…...

模拟QQ登录-课后程序(JAVA基础案例教程-黑马程序员编著-第十一章-课后作业)

【案例11-3】 模拟QQ登录 【案例介绍】 1.案例描述 QQ是现实生活中常用的聊天工具&#xff0c;QQ登录界面看似小巧、简单&#xff0c;但其中涉及的内容却很多&#xff0c;对于初学者练习Java Swing工具的使用非常合适。本案例要求使用所学的Java Swing知识&#xff0c;模拟实…...

【壹】嵌入式系统硬件基础

随手拍拍&#x1f481;‍♂️&#x1f4f7; 日期: 2023.2.28 地点: 杭州 介绍: 日子像旋转毒马&#x1f40e;&#xff0c;在脑海里转不停&#x1f92f; &#x1f332;&#x1f332;&#x1f332;&#x1f332;&#x1f332; 往期回顾 &#x1f332;&#x1f332;&#x1f332…...

当参数调优无法解决kafka消息积压时可以这么做

今天的议题是&#xff1a;如何快速处理kafka的消息积压 通常的做法有以下几种&#xff1a; 增加消费者数增加 topic 的分区数&#xff0c;从而进一步增加消费者数调整消费者参数&#xff0c;如max.poll.records增加硬件资源 常规手段不是本文的讨论重点或者当上面的手段已经使…...

Java线程池源码分析

Java 线程池的使用&#xff0c;是面试必问的。下面我们来从使用到源码整理一下。 1、构造线程池 通过Executors来构造线程池 1、构造一个固定线程数目的线程池&#xff0c;配置的corePoolSize与maximumPoolSize大小相同&#xff0c; 同时使用了一个无界LinkedBlockingQueue存…...

手撕八大排序(下)

目录 交换排序 冒泡排序&#xff1a; 快速排序 Hoare法 挖坑法 前后指针法【了解即可】 优化 再次优化&#xff08;插入排序&#xff09; 迭代法 其他排序 归并排序 计数排序 排序总结 结束了上半章四个较为简单的排序&#xff0c;接下来的难度将会大幅度上升&…...

SAP 详细解析SCC4

事务代码&#xff1a;SCC4&#xff0c;选择一个客户端&#xff0c;点击进入&#xff0c;如图&#xff1a; 一、客户端角色 客户控制&#xff1a;客户的角色&#xff08;生产性&#xff0c;测试&#xff0c;...&#xff09; 此属性表示 R/3 系统中的客户端角色。其中可能包括…...

java异常分类和finally代码块中return语句的影响

首先看一下java中异常相关类的继承关系&#xff1a; 引用 1、分类 异常可以分为受查异常和非受查异常&#xff0c;Error和RuntimeException及其所有的子类都是非受查异常&#xff0c;其他的是受查异常。 两者的区别主要在&#xff1a; 受检的异常是由编译器&#xff08;编译…...

【链表OJ题(二)】链表的中间节点

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;数据结构 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录链表OJ题(二)1. 链表…...

【强烈建议收藏:MySQL面试必问系列之并发事务锁专题】

一.知识回顾 上节课我们一起学习了MySQL面试必问系列之事务&#xff0c;没有学习的同学可以看一下上一篇文章&#xff0c;肯定对你会有帮助&#xff0c;学习过的同学肯定知道&#xff0c;上节课我们留了一个小尾巴&#xff0c;这个小尾巴是什么呢&#xff1f;就是没有详细展开…...

网站开发设计工具/网站关键词排名分析

对于该教程而言&#xff0c;缺少了删除已存在的电影记录的功能。因此&#xff0c;我在这里给出删除功能的代码供大家参考学习。 另外&#xff0c;需要注意的是要为VS2008打上SP1服务包&#xff0c;不然就不能使用ADO.NET Entity Data Model功能了。附按本教程制作的MovieDataba…...

集团公司网站模板/微信客户管理系统平台

计算机网络期末考试试卷及答案模板试卷号&#xff1a; 座位号:201 —201 学年度第一学期期末考试《计算机网络》试题A卷2013年 月题 号一二三四五总 分分 数得分 评卷人一、单项选择题(每小题2分&#xff0c;共30分)1&#xff0e;对于IP地址为 7的主机来说&#xff0c;其网络号…...

公司销售网站怎么做/长沙网站推广seo

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 本文链接&#xff1a;https://blog.csdn.net/wo541075754/article/details/81734770 在互联网中的每一刻&#xff0c;你可能都在享受着Base64带来…...

中国科技成就的例子/阿里巴巴seo排名优化

这是第一个类:publicclassStudents{//定义身高属性floatheight;}这是第二个类:publicclassHeight{publicfloatgetAvgHeight(Students[]stu){floatavgHeight0;floatall0;//所有学生身...这是第一个类:public class Students {//定义身高属性float height;}这是第二个类:public c…...

重庆网站开发商城/今天国际新闻最新消息

一、python语言基础 1.1变量变量.png 1.2数据类型数据类型.png 1.3序列 序列分类&#xff1a;可变序列list&#xff0c;不可变序列tuple、str。在python中&#xff0c;内建了6中序列&#xff1a;列表、元组、字符串、unicode字符串、buffer对象、xrange对象。 (1)list列表list列…...

下载网站后台/怎么网站推广

1、大部分SDK的方法需要在线程中执行&#xff0c;一般会放在主线程里执行&#xff0c;安卓中主线程一般用于UI渲染。 1 this.runOnUiThread(new Runnable() { 2 3 Override 4 public void run() { 5 // TODO Auto-generated method …...