{"id":21308007,"url":"https://github.com/weileifrank/cipherbaseonjava","last_synced_at":"2026-05-20T03:34:22.949Z","repository":{"id":215722762,"uuid":"159448352","full_name":"weileifrank/CipherBaseOnJava","owner":"weileifrank","description":"java des aes rsa ecc cipher android","archived":false,"fork":false,"pushed_at":"2019-01-18T03:27:13.000Z","size":461,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-22T09:14:06.201Z","etag":null,"topics":["aes","android","cipher","des","ecc","java","rsa"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/weileifrank.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-11-28T05:25:36.000Z","updated_at":"2019-04-09T02:52:11.000Z","dependencies_parsed_at":"2024-01-06T06:02:14.694Z","dependency_job_id":"eb942766-95a6-4288-b952-eba80cbc07ae","html_url":"https://github.com/weileifrank/CipherBaseOnJava","commit_stats":null,"previous_names":["weileifrank/cipherbaseonjava"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weileifrank%2FCipherBaseOnJava","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weileifrank%2FCipherBaseOnJava/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weileifrank%2FCipherBaseOnJava/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weileifrank%2FCipherBaseOnJava/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/weileifrank","download_url":"https://codeload.github.com/weileifrank/CipherBaseOnJava/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243785089,"owners_count":20347409,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aes","android","cipher","des","ecc","java","rsa"],"created_at":"2024-11-21T16:35:58.712Z","updated_at":"2026-05-20T03:34:17.928Z","avatar_url":"https://github.com/weileifrank.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Java密码学相关知识梳理\n## ASCII编码\n* ASCII（American Standard Code for Information Interchange，美国信息交换标准代码）是基于拉丁字母的一套电脑编码系统，主要用于显示现代英语和其他西欧语言。。\n* ![Logo](imgs/ascii.jpg)\n* 实例代码:\n```$java\npublic static void main(String[] args) {\n        char a = 'A';\n        int code = a;\n        System.out.println(code);\n\n        String s = \"frank\";\n        char[] chars = s.toCharArray();\n        for (char c : chars) {\n            int num = c;\n            System.out.println(num);\n        }\n}\n```\n## 凯撒加密\n* 恺撒密码（Caesar cipher）是一种相传尤利乌斯·恺撒曾使用过的密码。恺撒于公元前100年左右诞生于古罗马，是一位著名的军事统帅。\n* 恺撤密码是通过将明文中所使用的字母表按照一定的字数“平移”来进行加密的\n* ![Logo](imgs/i002.jpg)\n* 凯撒密码加解密公式\n  \n    - 加密\n    \n         ![](imgs/513169b7dcabfc4de6d4fcbc03e613434244e917.svg)\n    \n    - 解密\n    \n        ![](imgs/110911f42b858bdf1bec629ae41b5b88b00859e2.svg)\n    \n\n  - 凯撒密码中的加密三要素\n    - 明文/密文\n      - 明文: 图表上部分的数据\n      - 密文: 图表下部分的数据\n    - 秘钥\n      - 按照上图秘钥为3\n    - 算法\n      - 加密: +3\n      - 解密: -3\n* 示例代码如下:\n```$java\npublic static void main(String[] args) {\n        String s = \"frank\";\n        int key = 3;\n        String encriptData = KaiserEncrypt(s, key);\n        System.out.println(\"encriptData=\"+encriptData);\n        String decriptData = KaiserDecrypt(encriptData, key);\n        System.out.println(\"decriptData=\"+decriptData);\n        /**\n         * result as below:\n         * encriptData=iudqn\n         * decriptData=frank\n         */\n    }\n\n    /**\n     *\n     * @param orignal:原文\n     * @param key:秘钥\n     * @return:返回值\n     */\n    private static String KaiserEncrypt(String orignal, int key) {\n        char[] chars = orignal.toCharArray();\n        StringBuilder sb = new StringBuilder();\n        for (char aChar : chars) {\n            // 获取字符的ASCII编码\n            int asciiCode = aChar;\n            // 偏移数据\n            asciiCode += key;\n            // 将偏移后的数据转为字符\n            char result = (char) asciiCode;\n            // 拼接数据\n            sb.append(result);\n        }\n        return sb.toString();\n    }\n\n    /**\n     *\n     * @param encryptedData 密文\n     * @param key 秘钥\n     * @return\n     */\n    private static String KaiserDecrypt(String encryptedData, int key) {\n        char[] chars = encryptedData.toCharArray();\n        StringBuilder sb = new StringBuilder();\n        for (char aChar : chars) {\n            int asciiCode = aChar;\n            asciiCode -= key;\n            char result = (char) asciiCode;\n            sb.append(result);\n        }\n        return sb.toString();\n    }\n```\n## 频度分析法破解恺撒加密\n- 将明文字母的出现频率与密文字母的频率相比较的过程\n- 通过分析每个符号出现的频率而轻易地破译代换式密码\n- 在每种语言中，冗长的文章中的字母表现出一种可对之进行分辨的频率。\n- e是英语中最常用的字母，其出现频率为八分之一\n- 由于破解太简单,在此不贴代码了,有兴趣的自己试试\n\n## 对称加密\n\u003e 以分组为单位进行处理的密码算法称为**分组密码（blockcipher）**\n![Logo](imgs/i003.png)\n- 对称加密采用单钥密码系统的加密方法，同一个密钥可以同时用作信息的加密和解密，这种加密方法称为对称加密，也称为单密钥加密。\n- 示例\n  - 我们现在有一个原文3要发送给B\n  - 设置密钥为108, 3 * 108 = 324, 将324作为密文发送给B\n  - B拿到密文324后, 使用324/108 = 3 得到原文\n- 常见对称加密算法\n  - DES : Data Encryption Standard，即数据加密标准，是一种使用密钥加密的块算法，1977年被美国联邦政府的国家标准局确定为联邦资料处理标准（FIPS），并授权在非密级政府通信中使用，随后该算法在国际上广泛流传开来。\n  - AES : Advanced Encryption Standard, 高级加密标准 .在密码学中又称Rijndael加密法，是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES，已经被多方分析且广为全世界所使用。\n- 特点\n  - 加密速度快, 可以加密大文件\n  - 密文可逆, 一旦密钥文件泄漏, 就会导致数据暴露\n  - 加密后编码表找不到对应字符, 出现乱码\n  - 一般结合Base64使用 \n\n- 分组密码的模式\n    1. 按位异或\n    \n       - 第一步需要将数据转换为二进制\n    \n       - 按位异或操作符: ^\n    \n       - 两个标志位进行按位异或操作:\n    \n         - 相同为0, 不同为1\n    \n       - 举例:\n    \n         ```go\n         1 0 0 0   ----\u003e 8\n         1 0 1 1   ----\u003e 11\n         -----------------------按位异或一次\n         0 0 1 1   ----\u003e  3\n         1 0 1 1   ----\u003e 11\n         -----------------------按位异或两侧\n         1 0 0 0   -----\u003e 8\n         =================================\n         a = 8\n         b = 11\n         a 和 b按位异或1次 ==\u003e 加密\n         得到的结果再次和 b 按位异或 ===\u003e 解密\n         ```\n    \n    2. ECB - Electronic Code Book, 电子密码本模式\n    \n       - 特点: 简单, 效率高, 密文有规律, 容易被破解\n       - 最后一个明文分组必须要填充\n         - des/3des -\u003e 最后一个分组填充满8字节\n         - aes -\u003e 最后一个分组填充满16字节\n       - 不需要初始化向量\n    \n    3. CBC - Cipher Block Chaining, 密码块链模式\n    \n       - 特点: 密文没有规律, 经常使用的加密方式\n       - 最后一个明文分组需要填充\n         - des/3des -\u003e 最后一个分组填充满8字节\n         - aes -\u003e 最后一个分组填充满16字节\n       - 需要一个初始化向量 - 一个数组\n         - 数组的长度: 与明文分组相等\n         - 数据来源: 负责加密的人的提供的\n         - 加解密使用的初始化向量值必须相同\n    \n    4. CFB - Cipher FeedBack, 密文反馈模式\n    \n       - 特点: 密文没有规律,  明文分组是和一个数据流进行的按位异或操作, 最终生成了密文\n       - 需要一个初始化向量 - 一个数组\n         - 数组的长度: 与明文分组相等\n         - 数据来源: 负责加密的人的提供的\n         - 加解密使用的初始化向量值必须相同\n       - 不需要填充\n    \n    5. OFB - Output-Feedback, 输出反馈模式\n    \n       - 特点: 密文没有规律,  明文分组是和一个数据流进行的按位异或操作, 最终生成了密文\n       - 需要一个初始化向量 - 一个数组\n         - 数组的长度: 与明文分组相等\n         - 数据来源: 负责加密的人的提供的\n         - 加解密使用的初始化向量值必须相同\n       - 不需要填充\n    \n    6. CTR - CounTeR, 计数器模式\n    \n       - 特点: 密文没有规律,  明文分组是和一个数据流进行的按位异或操作, 最终生成了密文\n       - 不需要初始化向量\n       - 不需要填充\n    \n    7. 最后一个明文分组的填充\n    \n       - 使用cbc, ecb需要填充\n         - 要求: \n           - 明文分组中进行了填充, 然后加密\n           - 解密密文得到明文, 需要把填充的字节删除\n       - 使用 ofb, cfb, ctr不需要填充\n    \n    8. 初始化向量 - IV\n    \n       - ecb, ctr模式不需要初始化向量\n       - cbc, ofc, cfb需要初始化向量\n         - 初始化向量的长度\n           - des/3des -\u003e 8字节\n           - aes -\u003e 16字节\n         - 加解密使用的初始化向量相同\n    \n - DES加密示例代码如下:\n    - DES加密,key的大小必须是8个字节\n    - 如果没有指定分组密码模式和填充模式,ECB/PKCS5Padding就是默认值\n    - 如果指定分组密码模式为CBC,必须指定初始向量,初始向量中密钥的长度必须是8个字节\n    - NoPadding模式,原文的长度必须是8个字节的整倍数\n ```$xslt\n public class DESDemo {\n     // DES加密算法,key的大小必须是8个字节\n     public static void main(String[] args) throws Exception {\n         String input = \"frank\";\n         String key = \"12345678\";\n         // 指定获取Cipher的算法,如果没有指定分组密码模式和填充模式,ECB/PKCS5Padding就是默认值\n         // CBC模式,必须指定初始向量,初始向量中密钥的长度必须是8个字节\n         // NoPadding模式,原文的长度必须是8个字节的整倍数\n //        String transformation = \"DES\";\n         String transformation = \"DES/CBC/PKCS5Padding\";\n         // 指定获取密钥的算法\n         String algorithm = \"DES\";\n         String encryptDES = DESEncrypt(input, key, transformation, algorithm);\n         System.out.println(\"加密:\" + encryptDES);\n         String s = DESDecrypt(encryptDES, key, transformation, algorithm);\n         System.out.println(\"解密:\" + s);\n     }\n \n     /**\n      *\n      * @param input  明文\n      * @param key   密钥(DES,密钥的长度必须是8个字节)\n      * @param transformation  获取Cipher对象的算法\n      * @param algorithm   获取密钥的算法\n      * @return  返回密文\n      * @throws Exception\n      */\n     private static String DESEncrypt(String input, String key, String transformation, String algorithm) throws Exception {\n         // 1,获取Cipher对象\n         Cipher cipher = Cipher.getInstance(transformation);\n         // 指定密钥规则\n         SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);\n         // 2.初始化向量的秘钥长度需要根据算法而定,des 8个字节长度  aes 16个字节长度\n         //这里为了方便,统一使用传来的秘钥\n         IvParameterSpec iv = new IvParameterSpec(key.getBytes());\n         cipher.init(Cipher.ENCRYPT_MODE, sks, iv);\n //        cipher.init(Cipher.ENCRYPT_MODE, sks);\n         // 3. 加密\n         byte[] bytes = cipher.doFinal(input.getBytes());\n         // 对数据进行Base64编码\n         String encode = Base64.encode(bytes);\n         return encode;\n     }\n \n    \n     private static String DESDecrypt(String input, String key, String transformation, String algorithm) throws Exception {\n         Cipher cipher = Cipher.getInstance(transformation);\n         SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);\n         IvParameterSpec iv = new IvParameterSpec(key.getBytes());\n         cipher.init(Cipher.DECRYPT_MODE, sks, iv);\n //         cipher.init(Cipher.DECRYPT_MODE, sks);\n         byte[] bytes = cipher.doFinal(Base64.decode(input));\n         return new String(bytes);\n     }\n }\n ```\n  - AES加密示例代码如下(AES和DES加密高度类似)\n     - AES加密,key的大小必须是16个字节\n     - 如果没有指定分组密码模式和填充模式,ECB/PKCS5Padding就是默认值\n     - 如果没有指定分组密码模式为CBC,必须指定初始向量,初始向量中密钥的长度必须是16个字节\n     - NoPadding模式,原文的长度必须是16个字节的整倍数\n```$xslt\npublic class AESDemo {\n    // AES加密算法,key的大小必须是16个字节\n    public static void main(String[] args) throws Exception {\n        String input = \"frank\";\n        String key = \"1234567887654321\";\n        // 指定获取Cipher的算法,如果没有指定分组密码模式和填充模式,ECB/PKCS5Padding就是默认值\n        // CBC模式,必须指定初始向量,初始向量中密钥的长度必须是16个字节\n        // NoPadding模式,原文的长度必须是16个字节的整倍数\n//        String transformation = \"AES\";\n        String transformation = \"AES/CBC/PKCS5Padding\";\n        // 指定获取密钥的算法\n        String algorithm = \"AES\";\n        String encryptAES = AESEncrypt(input, key, transformation, algorithm);\n        System.out.println(\"加密:\" + encryptAES);\n        String s = AESDecrypt(encryptAES, key, transformation, algorithm);\n        System.out.println(\"解密:\" + s);\n    }\n\n    /**\n     *\n     * @param input  明文\n     * @param key   密钥(AES,密钥的长度必须是16个字节)\n     * @param transformation  获取Cipher对象的算法\n     * @param algorithm   获取密钥的算法\n     * @return  返回密文\n     * @throws Exception\n     */\n    private static String AESEncrypt(String input, String key, String transformation, String algorithm) throws Exception {\n        // 1,获取Cipher对象\n        Cipher cipher = Cipher.getInstance(transformation);\n        // 指定密钥规则\n        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);\n        // 2.初始化向量的秘钥长度需要根据算法而定,des 8个字节长度  aes 16个字节长度\n        //这里为了方便,统一使用传来的秘钥\n        IvParameterSpec iv = new IvParameterSpec(key.getBytes());\n        cipher.init(Cipher.ENCRYPT_MODE, sks, iv);\n//        cipher.init(Cipher.ENCRYPT_MODE, sks);\n        // 3. 加密\n        byte[] bytes = cipher.doFinal(input.getBytes());\n        // 对数据进行Base64编码\n        String encode = Base64.encode(bytes);\n        return encode;\n    }\n\n\n    private static String AESDecrypt(String input, String key, String transformation, String algorithm) throws Exception {\n        Cipher cipher = Cipher.getInstance(transformation);\n        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);\n        IvParameterSpec iv = new IvParameterSpec(key.getBytes());\n        cipher.init(Cipher.DECRYPT_MODE, sks, iv);\n//         cipher.init(Cipher.DECRYPT_MODE, sks);\n        byte[] bytes = cipher.doFinal(Base64.decode(input));\n        return new String(bytes);\n    }\n}\n\n```\n\n## 非对称加密\n\n### 1.  对称加密的弊端\n\n- 秘钥分发困难\n\n- 可以通过非对称加密完成秘钥的分发\n\n  \u003e https\n  \u003e\n  \u003e Alice 和 Bob通信, Alice给bob发送数据, 使用对称加密的方式\n  \u003e\n  \u003e 1. 生成一个非对称的秘钥对, bob生成\n  \u003e 2. bob将公钥发送给alice\n  \u003e 3. alice生成一个用于对称加密的秘钥\n  \u003e 4. alice使用bob的公钥就对称加密的秘钥进行加密, 并且发送给bob\n  \u003e 5. bob使用私钥就数据解密, 得到对称加密的秘钥\n  \u003e 6. 通信的双方使用写好的秘钥进行对称加密数据加密\n\n### 2. 非对称加密的秘钥\n\n- 不存在秘钥分发困难的问题\n\n#### 2.1 场景分析\n\n数据对谁更重要, 谁就拿私钥\n\n- 直观上看: 私钥比公钥长\n- 使用第三方工具生成密钥对: 公钥文件xxx.pub xxx \n\n\u003e 1. 通信流程, 信息加密  （A写数据, 发送给B, 信息只允许B读）\n\u003e\n\u003e    A: 公钥\n\u003e\n\u003e    B: 私钥\n\u003e\n\u003e 2. 登录认证 （客户端要登录, 连接服务器, 向服务器请求个人数据）\n\u003e\n\u003e    客户端:  私钥\n\u003e\n\u003e    服务器:  公钥\n\u003e\n\u003e 3. 数字签名（表明信息没有受到伪造，确实是信息拥有者发出来的，附在信息原文的后面）\n\u003e\n\u003e    - 发送信息的人:   私钥\n\u003e    - 收到信息的人:   公钥\n\u003e\n\u003e 4. 网银U盾\n\u003e\n\u003e    - 个人: 私钥\n\u003e    - 银行拿公钥\n\n### 3. 使用RSA非对称加密通信流程\n\n\u003e 要求: Alice 给 bob发送数据, 保证数据信息只有bob能看到\n\n### 4. 生成RSA的秘钥对\n#### 4.1 一些概念\n\n1. x509证书规范、pem、base64\n   - pem编码规范 - 数据加密\n   - base64 - 对数据编码, 可逆\n     - 不管原始数据是什么, 将原始数据使用64个字符来替代\n       - a-z  A-Z 0-9 + /\n2. ASN.1抽象语法标记\n3. PKCS1标准\n\n### 5. 常见算法\n\n\u003e RSA\n\n\u003e ECC(java需要借助第三方库实现加密解密,我将在另外一个项目中用go实现)\n\n###6 RSA示例代码如下\n   - 注意:经测试在后端使用Cipher.getInstance(“RSA”)加密,在移动端获取解密的Cipher类时要使用Cipher.getInstance(“RSA/ECB/PKCS1Padding”)\n   \n   - 移动端核心代码\n```$java\n  //后端用私钥加密过的数据\n    String eText = \"ETLPedgx7vR9E9JGNIj4pLhvurcOM26oo4RgJhmeF5RvDXVdl3qQ+5H6hmUx3dV2K8jPxi5aKSVs1xnjuMgSfK32fjrqzYBULFaBCmnN1HbpcwYFNMA3enWiVwT3TAWFKA9ReJ2DWh0lkCzaHruOmcWCY3f2tjuEE9X9L0DN7m5R9iy2qgEEDPgfzImYYl8wltYdudryz2fQ7UNGdIUPc75EMqdvHEUrxIi5A7cM0BDGQI2aXD+39ijQCOVBtai/9ohF7YXtGmbsocPBKarhe8qpVIcvXza6fBbOWxBC6Z68uRGcljTVkhvNjWrEmRuu5pc3C41bx4OK9FD8kPgITg==\";\n    //后端给的公钥\n    String pkey = \"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmpz9g5IX3ElRtXFo2+9nwD4+amqhEH4Rz1FI2cXeSiQeLPfdCoSsflLovdJ21NxvcKGw9IvmjWkLESCVU/pxDeP2UkVXFAjC2KhZvoQO4v0x4Yn3/55bAAQ9O3qoGatjPlDbzr1CEAi+ZA7NY1Oz2TtOSq8Odc7wc3Sq6U1gZBf87w5jq0GwQwgLrQjaVf5oTgKmavyf6g8Uq8U0QnktXCJpJUsSSZdeWTwAhtKk+MDkd5VRHIynLklOgeAhjG7xzEAad/Q32qLGcCwY+ySiZWLZ5q5uZAys4rj98LiwV6zLyk8CYYclUDUtBPLLXDRN8DUEe4uKAucFC4IlkrXQ0wIDAQAB\";\n    //获取公钥对象\n    KeyFactory keyFactory = KeyFactory.getInstance(algorithm);\n    X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(pkey, Base64.DEFAULT));\n    PublicKey publicKey = keyFactory.generatePublic(spec);\n    //指定解密algorithm = \"RSA/ECB/PKCS1Padding\"; Cipher cipher = Cipher.getInstance(algorithm);\n    algorithm = \"RSA/ECB/PKCS1Padding\";\n    String decrypt = RSADemo.RSADecrypt(algorithm, publicKey, eText, 256);\n    System.out.println(\"decript###\" + decrypt + \"###\");\n```\n\n - 后端代码  \n```java\npublic class RSADemo {\n    private static int MAX_ENCRIPT_SIZE = 200;\n\n    public static void main(String[] args) throws Exception {\n        String algorithm = \"RSA\";\n        String input = \"frank\";\n//        generateKeys(algorithm, \"test.pri\", \"test.pub\");\n\n        PrivateKey privateKey = getPrivateKey(\"test.pri\", algorithm);\n        PublicKey publicKey = getPublicKey(\"test.pub\", algorithm);\n\n        String encryptData = RSAEncrypt(algorithm, privateKey, input, MAX_ENCRIPT_SIZE);\n        System.out.println(\"encryptData=\" + encryptData);\n        String decryptData = RSADecrypt(algorithm, publicKey, encryptData, 256);\n        System.out.println(\"decryptData=\" + decryptData);\n\n    }\n\n    public static PrivateKey getPrivateKey(String priPath, String algorithm) throws Exception {\n        String privateKeyString = FileUtils.readFileToString(new File(priPath), Charset.defaultCharset());\n        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);\n        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyString));\n        return keyFactory.generatePrivate(spec);\n    }\n\n    public static PublicKey getPublicKey(String pubPath, String algorithm) throws Exception {\n        String publicKeyString = FileUtils.readFileToString(new File(pubPath), Charset.defaultCharset());\n        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);\n        X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(publicKeyString));\n        return keyFactory.generatePublic(spec);\n    }\n\n    public static void generateKeys(String algorithm, String priPath, String pubPath) throws Exception {\n        // 获取密钥对生成器\n        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);\n        // 获取密钥对\n        KeyPair keyPair = keyPairGenerator.generateKeyPair();\n        // 获取公私钥\n        PrivateKey privateKey = keyPair.getPrivate();\n        PublicKey publicKey = keyPair.getPublic();\n        // 获取公私钥的字节数组\n        byte[] privateKeyEncoded = privateKey.getEncoded();\n        byte[] publicKeyEncoded = publicKey.getEncoded();\n        // 对公私钥进行Base64的编码\n        String privateKeyString = Base64.encode(privateKeyEncoded);\n        String publicKeyString = Base64.encode(publicKeyEncoded);\n\n        FileUtils.writeStringToFile(new File(priPath), privateKeyString, Charset.defaultCharset());\n        FileUtils.writeStringToFile(new File(pubPath), publicKeyString, Charset.defaultCharset());\n    }\n\n    public static String RSAEncrypt(String algorithm, Key key, String input, int maxEncryptSize) throws Exception {\n        Cipher cipher = Cipher.getInstance(algorithm);\n        cipher.init(Cipher.ENCRYPT_MODE, key);\n        byte[] data = input.getBytes();\n        int total = data.length;\n        int offset = 0;\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        byte[] bytes;\n        while (total - offset \u003e 0) {\n            if (total - offset \u003e= maxEncryptSize) {\n                bytes = cipher.doFinal(data, offset, maxEncryptSize);\n                offset += maxEncryptSize;\n            } else {\n                bytes = cipher.doFinal(data, offset, total - offset);\n                offset = total;\n            }\n            baos.write(bytes);\n        }\n        return Base64.encode(baos.toByteArray());\n    }\n\n    public static String RSADecrypt(String algorithm, Key key, String input, int maxEncryptSize) throws Exception {\n        Cipher cipher = Cipher.getInstance(algorithm);\n        cipher.init(Cipher.DECRYPT_MODE, key);\n        byte[] data = Base64.decode(input);\n        int total = data.length;\n        int offset = 0;\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        byte[] bytes;\n        while (total - offset \u003e 0) {\n            if (total - offset \u003e= maxEncryptSize) {\n                bytes = cipher.doFinal(data, offset, maxEncryptSize);\n                offset += maxEncryptSize;\n            } else {\n                bytes = cipher.doFinal(data, offset, total - offset);\n                offset = total;\n            }\n            baos.write(bytes);\n        }\n        return baos.toString();\n    }\n}\n```\n\n\u003e 由于篇幅有点长,我将在另外一篇介绍哈希函数和数字签名","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweileifrank%2Fcipherbaseonjava","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fweileifrank%2Fcipherbaseonjava","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweileifrank%2Fcipherbaseonjava/lists"}