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里传输,因为URL编码器会把标准 Base64 中的“/”和“”字符变为形如 “%XX” 的形式,而这些 “%” 号在存入数据库时还需要再进行转换&…...
改进YOLO系列 | ICLR2022 | OMNI-DIMENSIONAL DYNAMIC CONVOLUTION: 全维动态卷积
单个静态卷积核是现代卷积神经网络(CNNs)的常见训练范式。然而,最近的动态卷积研究表明,学习加权为其输入依赖注意力的n个卷积核的线性组合可以显著提高轻量级CNNs的准确性,同时保持高效的推理。然而,我们观察到现有的作品通过卷积核空间的一个维度(关于卷积核数量)赋予…...
信息收集之Github搜索语法
信息收集之Github搜索语法1.Github的搜索语法2.使用 Github 进行邮件配置信息收集3.使用Github进行数据库信息收集4.使用Github进行 SVN 信息收集5.使用Github进行综合信息收集在测试的信息收集阶段,可以去Github和码云上搜索与目标有关的信息,或者就有意…...
【案例教程】拉格朗日粒子扩散模式FLEXPART
拉格朗日粒子扩散模式FLEXPART通过计算点、线、面或体积源释放的大量粒子的轨迹,来描述示踪物在大气中长距离、中尺度的传输、扩散、干湿沉降和辐射衰减等过程。该模式既可以通过时间的前向运算来模拟示踪物由源区向周围的扩散,也可以通过后向运算来确定…...
试题 算法训练 自行车停放
问题描述 有n辆自行车依次来到停车棚,除了第一辆自行车外,每辆自行车都会恰好停放在已经在停车棚里的某辆自行车的左边或右边。(e.g.停车棚里已经有3辆自行车,从左到右编号为:3,5,1。现在编号为2的第4辆自行车要停在5号自行车的左…...
泛型与Map接口
Java学习之道 泛型 泛型这种参数类型可以用在类、方法和接口中,分别被称为泛型类,泛型方法,泛型接口 参数化类型:将类型由原来的具体的类型参数化,在使用/调用时传入具体的类型JDK5引入特性提供了安全检测机制…...
Unity Bug记录本
//个人记录,持续更新 1、将此代码挂载到空脚本上: bool flag (object)GetComponent<Camera>() null; bool flag1 (object)GetComponent<Text>() null; Debug.Log(flag"::"flag1); //输出结果: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)
文章目录整体思路实现方法第一步第二步第三步第四步各位看官们大家好,上一回中咱们说的例子是"自定义Dialog主题",这一回中咱们说的例子是" 自定义Dialog"。闲话休提,言归正转, 让我们一起Talk Android吧!整体…...
GinVueAdmin源码分析3-整合MySQL
目录文件结构数据库准备配置文件处理config.godb_list.gogorm_mysql.gosystem.go初始化数据库gorm.gogorm_mysql.go开始初始化测试数据库定义实体类 Userserviceapi开始测试!文件结构 本文章将使用到上一节创建的 CommonService 接口,用于测试连接数据库…...
大数据框架之Hadoop:MapReduce(三)MapReduce框架原理——MapReduce开发总结
在编写MapReduce程序时,需要考虑如下几个方面: 1、输入数据接口:InputFormat 默认使用的实现类是:TextInputFormatTextInputFormat的功能逻辑是:一次读一行文本,然后将该行的起始偏移量作为key࿰…...
requests---(4)发送post请求完成登录
前段时间写过一个通过cookies完成登录,今天我们写一篇通过post发送请求完成登录豆瓣网 模拟登录 1、首先找到豆瓣网的登录接口 打开豆瓣网站的登录接口,请求错误的账号密码,通过F12或者抓包工具找到登录接口 通过F12抓包获取到请求登录接口…...
Python抓取数据具体流程
之前看了一段有关爬虫的网课深有启发,于是自己也尝试着如如何过去爬虫百科“python”词条等相关页面的整个过程记录下来,方便后期其他人一起来学习。 抓取策略 确定目标:重要的是先确定需要抓取的网站具体的那些部分,下面实例是…...
【Python学习笔记】第二十四节 Python 正则表达式
一、正则表达式简介正则表达式(regular expression)是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特…...
数字逻辑基础:原码、反码、补码
时间紧、不理解可以只看这里的结论 正数的原码、反码、补码相同。等于真值对应的机器码。 负数的原码等于机器码,反码为原码的符号位不变,其余各位按位取反。补码为反码1。 三种码的出现是为了解决计算问题并简化电路结构。 在原码和反码中,存…...
有限差分法-差商公式及其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 ,并满足: maxLocal[i][j] 等于 grid 中以 i 1 行和 j 1 列为中心的 3 x 3 矩阵中的 最大值 。 换句话说,我们希望找出 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 的二维矩阵,其中的每个元素都是一个 [1,9] 之间的正整数。 从矩阵中的任意位置出发…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...
