[转帖]数据加密之加密算法
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
:数据加密之加密算法 encrypt-decrypt1 密码学基本概念1.1 古典密码学1.2 近代密码学1.3 现代密码学2 凯撒加密2.1 凯撒加密解密的实现public class KaiSaUtil { // 加密 public static String encryptKaiser(String original, Integer key) { // 1、将输入的字符串转换成字符数组 char[] chars = original.toCharArray(); StringBuilder sb = new StringBuilder(); for (char aChar : chars) { // 2、获取字符的ascii编码 int asciiCode = aChar; // 3、偏移数据 asciiCode += key; // 4、将偏移后的数据转为字符 char result = (char) asciiCode; // 5、拼接数据 sb.append(result); } return sb.toString(); } // 解密 public static String decryptKaiser(String encryptedData, int key) { // 1、将密文转换成字符数组 char[] chars = encryptedData.toCharArray(); StringBuilder sb = new StringBuilder(); for (char aChar : chars) { // 2、获取字符的ascii编码 int asciiCode = aChar; // 3、偏移数据 asciiCode -= key; // 4、将偏移后的数据转为字符 char result = (char) asciiCode; // 5、拼接数据 sb.append(result); } return sb.toString(); }}123456789101112131415161718192021222324252627282930313233343536 public class KaiSaDemo { public static void main(String[] args) { String input = "welcome"; Integer key = 3; System.out.println("加密前:" + input); String encryptKaiser = KaiSaUtil.encryptKaiser(input, key); System.out.println("加密后:" + encryptKaiser); String decryptKaiser = KaiSaUtil.decryptKaiser(encryptKaiser, key); System.out.println("解密后:" + decryptKaiser); }}测试结果: 加密前:welcome 加密后:zhofrph 解密后:welcome123456789101112131415 2.2 使用频度分析法破解凯撒加密public static void main(String[] args) throws Exception { //测试1,统计字符个数 //printCharCount("article.txt"); //加密文件 int key = 3; encryptFile("article.txt", "article_en.txt", key); //读取加密后的文件 // String artile = Util.file2String("article_en.txt"); //解密(会生成多个备选文件) // decryptCaesarCode(artile, "article_de.txt"); }12345678910111213 public static void main(String[] args) throws Exception { //测试1,统计字符个数 printCharCount("article_en.txt"); //加密文件 int key = 3; //encryptFile("article.txt", "article_en.txt", key); //读取加密后的文件 // String artile = Util.file2String("article_en.txt"); //解密(会生成多个备选文件) // decryptCaesarCode(artile, "article_de.txt"); }12345678910111213 public class FrequencyUtil { public static void print(byte[] bytes) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < bytes.length; i++) { sb.append(bytes[i]).append(" "); } System.out.println(sb); } public static String file2String(String path) throws IOException { FileReader reader = new FileReader(new File(path)); char[] buffer = new char[1024]; int len = -1; StringBuffer sb = new StringBuffer(); while ((len = reader.read(buffer)) != -1) { sb.append(buffer, 0, len); } return sb.toString(); } public static void string2File(String data, String path) { FileWriter writer = null; try { writer = new FileWriter(new File(path)); writer.write(data); } catch (Exception e) { e.printStackTrace(); } finally { if (writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static String inputStream2String(InputStream in) throws IOException { int len = -1; byte[] buffer = new byte[1024]; ByteArrayOutputStream baos = new ByteArrayOutputStream(); while ((len = in.read(buffer)) != -1) { baos.write(buffer, 0, len); } baos.close(); return baos.toString("UTF-8"); }}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 public class FrequencyAnalysis { //英文里出现次数最多的字符 private static final char MAGIC_CHAR = 'e'; //破解生成的最大文件数 private static final int DE_MAX_FILE = 4; public static void main(String[] args) throws Exception { //测试1,统计字符个数// printCharCount("D:\\IDEA\\encrypt-decrypt\\src\\article.txt"); //加密文件 int key = 3;// encryptFile("D:\\\\IDEA\\\\encrypt-decrypt\\\\src\\\\article.txt", "D:\\IDEA\\encrypt-decrypt\\src\\article_en.txt", key); //读取加密后的文件 String artile = FrequencyUtil.file2String("D:\\IDEA\\encrypt-decrypt\\src\\article_en.txt"); //解密(会生成多个备选文件) decryptCaesarCode(artile, "article_de.txt"); } public static void printCharCount(String path) throws IOException { String data = FrequencyUtil.file2String(path); List<Entry<Character, Integer>> mapList = getMaxCountChar(data); for (Entry<Character, Integer> entry : mapList) { //输出前几位的统计信息 System.out.println("字符'" + entry.getKey() + "'出现" + entry.getValue() + "次"); } } public static void encryptFile(String srcFile, String destFile, int key) throws IOException { String artile = FrequencyUtil.file2String(srcFile); //加密文件 String encryptData = KaiSaUtil.encryptKaiser(artile, key); //保存加密后的文件 FrequencyUtil.string2File(encryptData, destFile); } /** * 破解凯撒密码 * * @param input 数据源 * @return 返回解密后的数据 */ public static void decryptCaesarCode(String input, String destPath) { int deCount = 0;//当前解密生成的备选文件数 //获取出现频率最高的字符信息(出现次数越多越靠前) List<Entry<Character, Integer>> mapList = getMaxCountChar(input); for (Entry<Character, Integer> entry : mapList) { //限制解密文件备选数 if (deCount >= DE_MAX_FILE) { break; } //输出前几位的统计信息 System.out.println("字符'" + entry.getKey() + "'出现" + entry.getValue() + "次"); ++deCount; //出现次数最高的字符跟MAGIC_CHAR的偏移量即为秘钥 int key = entry.getKey() - MAGIC_CHAR; System.out.println("猜测key = " + key + ", 解密生成第" + deCount + "个备选文件" + "\n"); String decrypt = KaiSaUtil.decryptKaiser(input, key); String fileName = "de_" + deCount + destPath; FrequencyUtil.string2File(decrypt, fileName); } } //统计String里出现最多的字符 public static List<Entry<Character, Integer>> getMaxCountChar(String data) { Map<Character, Integer> map = new HashMap<Character, Integer>(); char[] array = data.toCharArray(); for (char c : array) { if (!map.containsKey(c)) { map.put(c, 1); } else { Integer count = map.get(c); map.put(c, count + 1); } } //输出统计信息 for (Entry<Character, Integer> entry : map.entrySet()) { System.out.println(entry.getKey() + "出现" + entry.getValue() + "次"); } //获取获取最大值 int maxCount = 0; for (Entry<Character, Integer> entry : map.entrySet()) { //不统计空格 if (/*entry.getKey() != ' ' && */entry.getValue() > maxCount) { maxCount = entry.getValue(); } } //map转换成list便于排序 List<Entry<Character, Integer>> mapList = new ArrayList<Map.Entry<Character, Integer>>(map.entrySet()); //根据字符出现次数排序 Collections.sort(mapList, new Comparator<Entry<Character, Integer>>() { public int compare(Entry<Character, Integer> o1, Entry<Character, Integer> o2) { return o2.getValue().compareTo(o1.getValue()); } }); return mapList; }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 3 常见加密方式3.1 对称加密3.2 DES加密解密public class DesAesDemo { public static void main(String[] args) throws Exception { // 原文 String input = "hello"; // des加密必须是8位 String key = "12345678"; // 算法 String algorithm = "DES"; // 加密类型 String transformation = "DES"; // Cipher:密码,获取加密对象 // transformation:参数表示使用什么类型加密 Cipher cipher = Cipher.getInstance(transformation); // 指定秘钥规则 // 第一个参数表示:密钥,key的字节数组 // 第二个参数表示:算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 对加密进行初始化 // 第一个参数:表示模式,有加密模式和解密模式 // 第二个参数:表示秘钥规则 cipher.init(Cipher.ENCRYPT_MODE, sks); // 进行加密 byte[] bytes = cipher.doFinal(input.getBytes()); // 打印字节,因为ascii码有负数,解析不出来,所以乱码 for (byte b : bytes) { System.out.println(b); } // 打印密文 System.out.println(new String(bytes)); }}测试结果: -70 22 -58 -96 37 113 37 -81 �Ơ%q%�1234567891011121314151617181920212223242526272829303132333435363738394041 转码代码: String encode = Base64.encode(bytes); 测试结果: base64转码前:�i,6�M base64转码后:2GksNrsVEk0=123456 // 解密方法: public static String decryptDES(String input, String key, String transformation, String algorithm) throws Exception { // 1,获取Cipher对象 Cipher cipher = Cipher.getInstance(transformation); // 指定密钥规则 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); cipher.init(Cipher.DECRYPT_MODE, sks); // 3. 解密,上面使用的base64编码,下面直接用密文 byte[] bytes = cipher.doFinal(Base64.decode(input)); // 因为是明文,所以直接返回 return new String(bytes); }123456789101112 3.3 base64Base64是网络上最常见的用于传输8Bit字节码的可读性编码算法之一 可读性编码算法不是为了保护数据的安全性,而是为了可读性 可读性编码不改变信息内容,只改变信息内容的表现形式 所谓Base64,即是说在编码过程中使用了64种字符:大写A到Z、小写a到z、数字0到9、“+”和“/” Base58是Bitcoin(比特币)中使用的一种编码方式,主要用于产生Bitcoin的钱包地址 相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"i",以及"+"和"/"符号123456 public class TestBase64 { public static void main(String[] args) { // 1:MQ== 表示一个字节,不够三个字节,所以需要后面通过 == 号补齐 System.out.println(Base64.encode("1".getBytes()));// System.out.println(Base64.encode("12".getBytes()));// System.out.println(Base64.encode("123".getBytes()));// // 你好:中文占6个字节,6 * 8 = 48 ,刚刚好被整除,所以没有等号// System.out.println(Base64.encode("你好".getBytes())); }}测试结果: MQ== MTI= MTIZ123456789101112131415 3.4 AES加密解密public class AESUtil { // 加密方法 public static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception { // 获取加密对象 Cipher cipher = Cipher.getInstance(transformation); // 创建加密规则 // 第一个参数key的字节 // 第二个参数表示加密算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // ENCRYPT_MODE:加密模式 // DECRYPT_MODE: 解密模式 // 初始化加密模式和算法 cipher.init(Cipher.ENCRYPT_MODE,sks); // 加密 byte[] bytes = cipher.doFinal(input.getBytes()); // 输出加密后的数据 String encode = Base64.encode(bytes); return encode; } // 解密方法: public static String decryptDES(String input, String key, String transformation, String algorithm) throws Exception { // 1,获取Cipher对象 Cipher cipher = Cipher.getInstance(transformation); // 指定密钥规则 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); cipher.init(Cipher.DECRYPT_MODE, sks); // 3. 解密,上面使用的base64编码,下面直接用密文 byte[] bytes = cipher.doFinal(Base64.decode(input)); // 因为是明文,所以直接返回 return new String(bytes); }}1234567891011121314151617181920212223242526272829303132333435 public class AESDemo { public static void main(String[] args) throws Exception { String input = "原文"; // DES加密算法,key的大小必须是8个字节 String key = "1234567812345678"; String transformation = "AES"; // 指定获取密钥的算法 String algorithm = "AES"; String encryptDES = AESUtil.encryptDES(input, key, transformation, algorithm); System.out.println("加密:" + encryptDES); String s = AESUtil.decryptDES(encryptDES, key, transformation, algorithm); System.out.println("解密:" + s); }}测试结果: 加密:TUuxDy0h/Rx1KwhMFXEnog== 解密:原文1234567891011121314151617 3.5 toString()与new String ()用法区别4 加密模式5 填充模式AES/CBC/NoPadding (128)AES/CBC/PKCS5Padding (128)AES/ECB/NoPadding (128)AES/ECB/PKCS5Padding (128)DES/CBC/NoPadding (56)DES/CBC/PKCS5Padding (56)DES/ECB/NoPadding (56)DES/ECB/PKCS5Padding (56)DESede/CBC/NoPadding (168)DESede/CBC/PKCS5Padding (168)DESede/ECB/NoPadding (168)DESede/ECB/PKCS5Padding (168)RSA/ECB/PKCS1Padding (1024, 2048)RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)123456789101112131415 6 消息摘要- MD5- SHA1- SHA256- SHA5121234 bd465ea30ee7e0a66ed67e86d45a53aa5aba0c8d190934e7dfa58294a21ada7b967877d848e1836a19bf01437cab64f275ac827d81b3f3253eb961b60361a045 *apache-tomcat-10.0.2.exe1 // 消息摘要算法,为了防止篡改public class DigestDemo1 { public static void main(String[] args) throws NoSuchAlgorithmException { // 原文 String input = "aa"; // 算法 String algorithm = "MD5"; // 获取数字摘要对象 MessageDigest messageDigest = MessageDigest.getInstance(algorithm); // 获取消息数字摘要的字节数组 byte[] digest = messageDigest.digest(input.getBytes()); System.out.println(new String(digest)); // 结合base64解决转码 System.out.println(Base64.encode(digest)); }}测试结果: A$� �5�o$� zI 转码后:QSS8CpM1wn8IbyS6IHpJEg==123456789101112131415161718192021 // 4124bc0a9335c27f086f24ba207a4912 md5 在线校验 // QSS8CpM1wn8IbyS6IHpJEg== 消息摘要使用的是16进制12 // 消息摘要算法,为了防止篡改public class DigestDemo1 { public static void main(String[] args) throws NoSuchAlgorithmException { // 原文 String input = "aa"; // 算法 String algorithm = "MD5"; // 获取数字摘要对象 MessageDigest messageDigest = MessageDigest.getInstance(algorithm); // 获取消息数字摘要的字节数组 byte[] digest = messageDigest.digest(input.getBytes()); // 创建对象用来拼接 StringBuilder sb = new StringBuilder(); // 对密文进行迭代 for (byte b : digest) { // 转成 16进制 String s = Integer.toHexString(b & 0xff);// System.out.println(s); if (s.length() == 1){ // 如果生成的字符只有一个,前面补0 s = "0"+s; } sb.append(s); } System.out.println(sb.toString()); }}12345678910111213141516171819202122232425262728 public class DigestDemo12 { public static void main(String[] args) throws Exception { // 原文 String input = "aa"; // 算法 String algorithm = "MD5"; // 获取数字摘要对象 String md5 = getDigest(input, "MD5"); System.out.println(md5); String sha1 = getDigest(input, "SHA-1"); System.out.println(sha1); String sha256 = getDigest(input, "SHA-256"); System.out.println(sha256); String sha512 = getDigest(input, "SHA-512"); System.out.println(sha512); } private static String toHex(byte[] digest) throws Exception {// System.out.println(new String(digest)); // base64编码// System.out.println(Base64.encode(digest)); // 创建对象用来拼接 StringBuilder sb = new StringBuilder(); for (byte b : digest) { // 转成 16进制 String s = Integer.toHexString(b & 0xff); if (s.length() == 1) { // 如果生成的字符只有一个,前面补0 s = "0" + s; } sb.append(s); } System.out.println("16进制数据的长度:" + sb.toString().getBytes().length); return sb.toString(); } private static String getDigest(String input, String algorithm) throws Exception { MessageDigest messageDigest = MessageDigest.getInstance(algorithm); // 消息数字摘要 byte[] digest = messageDigest.digest(input.getBytes()); System.out.println("密文的字节长度:" + digest.length); return toHex(digest); }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 public class DigestDemo { public static void main(String[] args) throws Exception { String input = "aa"; String algorithm = "MD5"; // sha1 可以实现秒传功能 String sha1 = getDigestFile("D:\\apache-tomcat-9.0.41.zip", "SHA-1"); System.out.println(sha1); String sha512 = getDigestFile("D:\\apache-tomcat-9.0.41.zip", "SHA-512"); System.out.println(sha512); String md5 = getDigest("aa", "MD5"); System.out.println(md5); String md51 = getDigest("aa ", "MD5"); System.out.println(md51); } private static String getDigestFile(String filePath, String algorithm) throws Exception { FileInputStream fis = new FileInputStream(filePath); int len; byte[] buffer = new byte[1024]; ByteArrayOutputStream baos = new ByteArrayOutputStream(); while ((len = fis.read(buffer)) != -1) { baos.write(buffer, 0, len); } // 获取消息摘要对象 MessageDigest messageDigest = MessageDigest.getInstance(algorithm); // 获取消息摘要 byte[] digest = messageDigest.digest(baos.toByteArray()); System.out.println("密文的字节长度:" + digest.length); return toHex(digest); } private static String getDigest(String input, String algorithm) throws Exception { MessageDigest messageDigest = MessageDigest.getInstance(algorithm); byte[] digest = messageDigest.digest(input.getBytes()); System.out.println("密文的字节长度:" + digest.length); return toHex(digest); } private static String toHex(byte[] digest) { // System.out.println(new String(digest)); // 消息摘要进行表示的时候,是用16进制进行表示 StringBuilder sb = new StringBuilder(); for (byte b : digest) { // 转成16进制 String s = Integer.toHexString(b & 0xff); // 保持数据的完整性,前面不够的用0补齐 if (s.length() == 1) { s = "0" + s; } sb.append(s); } System.out.println("16进制数据的长度:" + sb.toString().getBytes().length); return sb.toString(); }}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 7 非对称加密7.1 生成公钥和私钥public class RSAdemo { public static void main(String[] args) throws Exception { // 加密算法 String algorithm = "RSA"; // 创建密钥对生成器对象 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm); // 生成密钥对 KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 生成私钥 PrivateKey privateKey = keyPair.getPrivate(); // 生成公钥 PublicKey publicKey = keyPair.getPublic(); // 获取私钥字节数组 byte[] privateKeyEncoded = privateKey.getEncoded(); // 获取公钥字节数组 byte[] publicKeyEncoded = publicKey.getEncoded(); // 对公私钥进行base64编码 String privateKeyString = Base64.encode(privateKeyEncoded); String publicKeyString = Base64.encode(publicKeyEncoded); // 打印私钥 System.out.println(privateKeyString); // 打印公钥 System.out.println(publicKeyString); }}12345678910111213141516171819202122232425 7.2 私钥加密// 私钥加密public class RSAdemo { public static void main(String[] args) throws Exception { String input = "hello"; // 加密算法 String algorithm = "RSA"; // 创建密钥对生成器对象 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm); // 生成密钥对 KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 生成私钥 PrivateKey privateKey = keyPair.getPrivate(); // 生成公钥 PublicKey publicKey = keyPair.getPublic(); // 获取私钥字节数组 byte[] privateKeyEncoded = privateKey.getEncoded(); // 获取公钥字节数组 byte[] publicKeyEncoded = publicKey.getEncoded(); // 对公私钥进行base64编码 String privateKeyString = Base64.encode(privateKeyEncoded); String publicKeyString = Base64.encode(publicKeyEncoded); // 创建加密对象 // 参数表示加密算法 Cipher cipher = Cipher.getInstance(algorithm); // 初始化加密 // 第一个参数:加密的模式 // 第二个参数:使用私钥进行加密 cipher.init(Cipher.ENCRYPT_MODE,privateKey); // 私钥加密 byte[] bytes = cipher.doFinal(input.getBytes()); System.out.println(Base64.encode(bytes)); }}123456789101112131415161718192021222324252627282930313233 7.3 私钥加密私钥解密public class RSAdemo2 { public static void main(String[] args) throws Exception { String input = "你好"; // 加密算法 String algorithm = "RSA"; // 创建密钥对生成器对象 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm); // 生成密钥对 KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 生成私钥 PrivateKey privateKey = keyPair.getPrivate(); // 生成公钥 PublicKey publicKey = keyPair.getPublic(); // 获取私钥字节数组 byte[] privateKeyEncoded = privateKey.getEncoded(); // 获取公钥字节数组 byte[] publicKeyEncoded = publicKey.getEncoded(); // 对公私钥进行base64编码 String privateKeyString = Base64.encode(privateKeyEncoded); String publicKeyString = Base64.encode(publicKeyEncoded); // 创建加密对象 // 参数表示加密算法 Cipher cipher = Cipher.getInstance(algorithm); // 初始化加密 // 第一个参数:加密的模式 // 第二个参数:使用私钥进行加密 cipher.init(Cipher.ENCRYPT_MODE, privateKey); // 私钥加密 byte[] bytes = cipher.doFinal(input.getBytes()); System.out.println("加密后:"+Base64.encode(bytes)); // 私钥进行解密 cipher.init(Cipher.DECRYPT_MODE, privateKey); // 对密文进行解密,不需要使用base64,因为原文不会乱码 byte[] bytes1 = cipher.doFinal(bytes); System.out.println("解密后:"+new String(bytes1)); }}12345678910111213141516171819202122232425262728293031323334353637383940 7.4 私钥加密公钥解密public class RSAdemo2 { public static void main(String[] args) throws Exception { String input = "你好"; // 加密算法 String algorithm = "RSA"; // 创建密钥对生成器对象 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm); // 生成密钥对 KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 生成私钥 PrivateKey privateKey = keyPair.getPrivate(); // 生成公钥 PublicKey publicKey = keyPair.getPublic(); // 获取私钥字节数组 byte[] privateKeyEncoded = privateKey.getEncoded(); // 获取公钥字节数组 byte[] publicKeyEncoded = publicKey.getEncoded(); // 对公私钥进行base64编码 String privateKeyString = Base64.encode(privateKeyEncoded); String publicKeyString = Base64.encode(publicKeyEncoded); // 创建加密对象 // 参数表示加密算法 Cipher cipher = Cipher.getInstance(algorithm); // 初始化加密 // 第一个参数:加密的模式 // 第二个参数:使用私钥进行加密 cipher.init(Cipher.ENCRYPT_MODE, privateKey); // 私钥加密 byte[] bytes = cipher.doFinal(input.getBytes()); System.out.println("加密后:"+Base64.encode(bytes)); // 公钥进行解密 cipher.init(Cipher.DECRYPT_MODE, publicKey); // 对密文进行解密,不需要使用base64,因为原文不会乱码 byte[] bytes1 = cipher.doFinal(bytes); System.out.println("解密后:"+new String(bytes1)); }}12345678910111213141516171819202122232425262728293031323334353637383940 7.5 保存公钥和私钥private static void generateKeyToFile(String algorithm, String pubPath, String priPath) throws Exception { // 获取密钥对生成器 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm); // 获取密钥对 KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 获取公钥 PublicKey publicKey = keyPair.getPublic(); // 获取私钥 PrivateKey privateKey = keyPair.getPrivate(); // 获取byte数组 byte[] publicKeyEncoded = publicKey.getEncoded(); byte[] privateKeyEncoded = privateKey.getEncoded(); // 进行Base64编码 String publicKeyString = Base64.encode(publicKeyEncoded); String privateKeyString = Base64.encode(privateKeyEncoded); // 保存文件 FileUtils.writeStringToFile(new File(pubPath), publicKeyString, Charset.forName("UTF-8")); FileUtils.writeStringToFile(new File(priPath), privateKeyString, Charset.forName("UTF-8")); }12345678910111213141516171819 7.6 读取私钥public static PrivateKey getPrivateKey(String priPath, String algorithm) throws Exception { // 将文件内容转为字符串 String privateKeyString = FileUtils.readFileToString(new File(priPath), Charset.defaultCharset()); // 输出私钥 System.out.println(privateKeyString); // 获取密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance(algorithm); // 构建密钥规范 进行Base64解码 PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyString)); // 生成私钥 return keyFactory.generatePrivate(spec); }123456789101112 7.7 读取公钥public static PublicKey getPublicKey(String pulickPath, String algorithm) throws Exception { // 将文件内容转为字符串 String publicKeyString = FileUtils.readFileToString(new File(pulickPath), Charset.defaultCharset()); System.out.println(publicKeyString); // 获取密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance(algorithm); // 构建密钥规范 进行Base64解码 X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(publicKeyString)); // 生成公钥 return keyFactory.generatePublic(spec); }123456789101112 7.8 RSA工具类<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version></dependency>12345 public class RSAUtil { private static final String KEY_ALGORITHM = "RSA"; private static KeyPairGenerator keyPairGenerator; // 为每一个字段生成公私密钥 public static void makeRsaKeys(String pubPath, String priPath, String user) throws Exception { try { keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } //随机数生成器 SecureRandom random = new SecureRandom(); //设置KEY_SIZE位长的秘钥 int KEY_SIZE = 1024; keyPairGenerator.initialize(KEY_SIZE, random); //开始创建 KeyPair keyPair = keyPairGenerator.generateKeyPair(); PublicKey publicKey = keyPair.getPublic();//公钥 PrivateKey privateKey = keyPair.getPrivate();//私钥 //使用Base64进行转码 String publicKeyStr = Base64.encode(publicKey.getEncoded()); String privateKeyStr = Base64.encode(privateKey.getEncoded()); // 保存文件 FileUtils.writeStringToFile(new File(pubPath), publicKeyStr, Charset.forName("UTF-8")); FileUtils.writeStringToFile(new File(priPath), privateKeyStr, Charset.forName("UTF-8")); } // 私钥加密 public static String privateKeyDecode(String data, int mode, String priPath) throws Exception { // 将文件内容转为字符串 String privateKeyString = FileUtils.readFileToString(new File(priPath), Charset.defaultCharset()); // 输出私钥// System.out.println(privateKeyString); // 获取密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 构建密钥规范 进行Base64解码 PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyString)); // 生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(spec); try { Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); if (mode == Cipher.ENCRYPT_MODE) {//加密 cipher.init(mode, privateKey); return Base64.encode(cipher.doFinal(data.getBytes())); } else if (mode == Cipher.DECRYPT_MODE) {//解密 cipher.init(mode, privateKey); return new String(cipher.doFinal(Base64.decode(data)), StandardCharsets.UTF_8); } else { return null; } } catch (Exception e) { e.printStackTrace(); return null; } } // 公钥解密 public static String publicKeyDecode(String data, String pulickPath, int mode) throws Exception { // 将文件内容转为字符串 String publicKeyString = FileUtils.readFileToString(new File(pulickPath), Charset.defaultCharset());// System.out.println(publicKeyString); // 获取密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 构建密钥规范 进行Base64解码 X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(publicKeyString)); // 生成公钥 PublicKey publicKey = keyFactory.generatePublic(spec); try { Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); if (mode == Cipher.ENCRYPT_MODE) {//加密 cipher.init(mode, publicKey); return Base64.encode(cipher.doFinal(data.getBytes())); } else if (mode == Cipher.DECRYPT_MODE) {//解密 cipher.init(mode, publicKey); byte[] bytes = cipher.doFinal(Base64.decode(data)); return new String(bytes, StandardCharsets.UTF_8); } else { return null; } } catch (Exception e) { e.printStackTrace(); return null; } } public static void main(String[] args) throws Exception { String user = "root"; // 公钥路径 String pubPath = "D:\\IDEA\\encrypt-decrypt\\src\\main\\java\\com\\zwh\\key\\" + user + ".txt"; // 私钥路径 String priPath = "D:\\IDEA\\encrypt-decrypt\\src\\main\\java\\com\\zwh\\key\\" + user + "_en.txt"; makeRsaKeys(pubPath, priPath, user); String str = "123456"; System.out.println("明文:" + str); System.out.println("---------私钥加密,公钥解密-----------"); String privateKeyDecode = privateKeyDecode(str, 1, priPath); System.out.println("私钥加密:" + privateKeyDecode); String publicKeyDecode = publicKeyDecode(privateKeyDecode, pubPath, 2); System.out.println("公钥解密:" + publicKeyDecode); }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 8 数字签名public class SignatureDemo { public static void main(String[] args) throws Exception { String a = "123"; PublicKey publicKey = RSAdemo4.getPublicKey("a.pub", "RSA"); PrivateKey privateKey = RSAdemo4.getPrivateKey("a.pri", "RSA"); String signaturedData = getSignature(a, "sha256withrsa", privateKey); boolean b = verifySignature(a, "sha256withrsa", publicKey, signaturedData); System.out.println(b); System.out.println(signaturedData); } /** * 生成签名 * * @param input : 原文 * @param algorithm : 算法 * @param privateKey : 私钥 * @return : 签名 * @throws Exception */ private static String getSignature(String input, String algorithm, PrivateKey privateKey) throws Exception { // 获取签名对象 Signature signature = Signature.getInstance(algorithm); // 初始化签名 signature.initSign(privateKey); // 传入原文 signature.update(input.getBytes()); // 开始签名 byte[] sign = signature.sign(); // 对签名数据进行Base64编码 return Base64.encode(sign); } /** * 校验签名 * * @param input : 原文 * @param algorithm : 算法 * @param publicKey : 公钥 * @param signaturedData : 签名 * @return : 数据是否被篡改 * @throws Exception */ private static boolean verifySignature(String input, String algorithm, PublicKey publicKey, String signaturedData) throws Exception { // 获取签名对象 Signature signature = Signature.getInstance(algorithm); // 初始化签名 signature.initVerify(publicKey); // 传入原文 signature.update(input.getBytes()); // 校验数据 return signature.verify(Base64.decode(signaturedData)); }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 该文章在 2023/6/2 10:10:50 编辑过 |
关键字查询
相关文章
正在查询... |