| [转帖]数据加密之加密算法
					当前位置:点晴教程→知识管理交流
					
					→『 技术文档交流 』
					
				 
  :数据加密之加密算法  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();
    }}123456789101112131415161718192021222324252627282930313233343536public 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
    解密后:welcome1234567891011121314152.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");
	}12345678910111213public 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");
	}12345678910111213public 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");
    }}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950public 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;
    }}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051063 常见加密方式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);
    }1234567891011123.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=
	MTIZ1234567891011121314153.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);
    }}1234567891011121314151617181920212223242526272829303132333435public 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==
    解密:原文12345678910111213141516173.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());
    }}12345678910111213141516171819202122232425262728public 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);
    }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051public 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();
    }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960617 非对称加密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);
    }}123456789101112131415161718192021222324257.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));
    }}1234567891011121314151617181920212223242526272829303132337.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));
    }}123456789101112131415161718192021222324252627282930313233343536373839407.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));
    }}123456789101112131415161718192021222324252627282930313233343536373839407.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"));
    }123456789101112131415161718197.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);
    }1234567891011127.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);
    }1234567891011127.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);
    }}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011028 数字签名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 编辑过 | 关键字查询 相关文章 正在查询... |