`

Java加密解密快速入门上篇【包括MD5、BASE64、DES、RSA等算法】

    博客分类:
  • Java
阅读更多

        搞Java的攻城狮应该比较欣喜若狂的,不仅Sun公司的JDK提供了庞大的类库,而且还有众多的开源组织和个人不断地丰富着Java的生态系统。没错的,诸如MD5、BASE64、DES、RSA等经典加密解密算法,JDK都有提供专门的API来封装相关操作。程序猿只需要了解算法的思想,以及学习如何使用API即可。吻当然,针对BASE64算法,JDK仅仅提供了非常标准的实现,在某些场景下无法满足应用需求。在最后一部分,将学习Apache提供的Commons Codec大笑对BASE64算法的扩展实现,以满足实践的需要。

 

<一>. MD5加密算法:

       消息摘要算法第五版(Message Digest Algorithm),是一种单向加密算法,只能加密、无法解密。然而MD5加密算法已经被中国山东大学王小云教授成功破译哭,但是在安全性要求不高的场景下,MD5加密算法仍然具有应用价值。

 1. 创建md5对象: 

Java代码 
  1. MessageDigest md5 = MessageDigest.getInstance("md5");  

 2.  进行加密操作: 

Java代码 
  1. byte[] cipherData = md5.digest(plainText.getBytes());  

 3.  将其中的每个字节转成十六进制字符串:byte类型的数据最高位是符号位,通过和0xff进行与操作,转换为int类型的正整数。 

Java代码 
  1. String toHexStr = Integer.toHexString(cipher & 0xff);  

 4. 如果该正数小于16(长度为1个字符),前面拼接0占位:确保最后生成的是32位字符串。 

Java代码 
  1. builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr);  

 5. 加密转换之后的字符串为:c0bb4f54f1d8b14caf6fe1069e5f93ad 

 6. 完整的MD5算法应用如下所示: 

Java代码 
  1. /** 
  2.  * 功能简述: 测试MD5单向加密. 
  3.  * @throws Exception 
  4.  */  
  5. @Test  
  6. public void test01() throws Exception {  
  7.     String plainText = "Hello , world !";  
  8.     MessageDigest md5 = MessageDigest.getInstance("md5");  
  9.     byte[] cipherData = md5.digest(plainText.getBytes());  
  10.     StringBuilder builder = new StringBuilder();  
  11.     for(byte cipher : cipherData) {  
  12.         String toHexStr = Integer.toHexString(cipher & 0xff);  
  13.         builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr);  
  14.     }  
  15.     System.out.println(builder.toString());  
  16.     //c0bb4f54f1d8b14caf6fe1069e5f93ad  
  17. }  

 

<二>. 使用BASE64进行加密/解密:

        使用BASE64算法通常用作对二进制数据进行加密,加密之后的数据不易被肉眼识别。严格来说,经过BASE64加密的数据其实没有安全性可言保密,因为它的加密解密算法都是公开的,典型的防菜鸟不防程序猿的呀。 经过标准的BASE64算法加密后的数据, 通常包含/、+、=等特殊符号,不适合作为url参数传递,幸运的是Apache的Commons Codec模块提供了对BASE64的进一步封装。  (参见最后一部分的说明)

 1. 使用BASE64加密: 

Java代码 
  1. BASE64Encoder encoder = new BASE64Encoder();  
  2. String cipherText = encoder.encode(plainText.getBytes());  

  2. 使用BASE64解密: 

Java代码 
  1. BASE64Decoder decoder = new BASE64Decoder();  
  2. plainText = new String(decoder.decodeBuffer(cipherText));  

  3. 完整代码示例: 

Java代码 
  1. /** 
  2.  * 功能简述: 使用BASE64进行双向加密/解密. 
  3.  * @throws Exception 
  4.  */  
  5. @Test  
  6. public void test02() throws Exception {  
  7.     BASE64Encoder encoder = new BASE64Encoder();  
  8.     BASE64Decoder decoder = new BASE64Decoder();  
  9.     String plainText = "Hello , world !";  
  10.     String cipherText = encoder.encode(plainText.getBytes());  
  11.     System.out.println("cipherText : " + cipherText);  
  12.     //cipherText : SGVsbG8gLCB3b3JsZCAh  
  13.     System.out.println("plainText : " +   
  14.         new String(decoder.decodeBuffer(cipherText)));  
  15.     //plainText : Hello , world !  

 

<三>. 使用DES对称加密/解密:

         数据加密标准算法(Data Encryption Standard),和BASE64最明显的区别就是有一个工作密钥,该密钥既用于加密、也用于解密,并且要求密钥是一个长度至少大于8位的字符串。使用DES加密、解密的核心是确保工作密钥的安全性。叫喊

 1. 根据key生成密钥: 

Java代码 
  1. DESKeySpec keySpec = new DESKeySpec(key.getBytes());  
  2. SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("des");  
  3. SecretKey secretKey = keyFactory.generateSecret(keySpec);  

  2. 加密操作: 

Java代码 
  1. Cipher cipher = Cipher.getInstance("des");  
  2. cipher.init(Cipher.ENCRYPT_MODE, secretKey, new SecureRandom());  
  3. byte[] cipherData = cipher.doFinal(plainText.getBytes());  

  3. 为了便于观察生成的加密数据,使用BASE64再次加密: 

Java代码 
  1. String cipherText = new BASE64Encoder().encode(cipherData);  

     生成密文如下:PtRYi3sp7TOR69UrKEIicA== 

  4. 解密操作: 

Java代码 
  1. cipher.init(Cipher.DECRYPT_MODE, secretKey, new SecureRandom());  
  2. byte[] plainData = cipher.doFinal(cipherData);  
  3. String plainText = new String(plainData);  

  5. 完整的代码demo: 

Java代码 
  1. /** 
  2.  * 功能简述: 使用DES对称加密/解密. 
  3.  * @throws Exception 
  4.  */  
  5. @Test  
  6. public void test03() throws Exception {  
  7.     String plainText = "Hello , world !";  
  8.     String key = "12345678";    //要求key至少长度为8个字符  
  9.       
  10.     SecureRandom random = new SecureRandom();  
  11.     DESKeySpec keySpec = new DESKeySpec(key.getBytes());  
  12.     SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("des");  
  13.     SecretKey secretKey = keyFactory.generateSecret(keySpec);  
  14.       
  15.     Cipher cipher = Cipher.getInstance("des");  
  16.     cipher.init(Cipher.ENCRYPT_MODE, secretKey, random);  
  17.     byte[] cipherData = cipher.doFinal(plainText.getBytes());  
  18.     System.out.println("cipherText : " + new BASE64Encoder().encode(cipherData));  
  19.     //PtRYi3sp7TOR69UrKEIicA==  
  20.       
  21.     cipher.init(Cipher.DECRYPT_MODE, secretKey, random);  
  22.     byte[] plainData = cipher.doFinal(cipherData);  
  23.     System.out.println("plainText : " + new String(plainData));  
  24.     //Hello , world !  
  25. }  

 

<四>. 使用RSA非对称加密/解密:

        RSA算法是非对称加密算法的典型代表,既能加密、又能解密。和对称加密算法比如DES的明显区别在于用于加密、解密的密钥是不同的。使用RSA算法,只要密钥足够长(一般要求1024bit),加密的信息是不能被破解的。天真用户通过https协议访问服务器时,就是使用非对称加密算法进行数据的加密、解密操作的。

       服务器发送数据给客户端时使用私钥(private key)进行加密,并且使用加密之后的数据和私钥生成数字签名(digital signature)并发送给客户端。客户端接收到服务器发送的数据会使用公钥(public key)对数据来进行解密,并且根据加密数据和公钥验证数字签名的有效性,防止加密数据在传输过程中被第三方进行了修改。

       客户端发送数据给服务器时使用公钥进行加密,服务器接收到加密数据之后使用私钥进行解密。

 1. 创建密钥对KeyPair:

Java代码 
  1. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("rsa");  
  2. keyPairGenerator.initialize(1024);  //密钥长度推荐为1024位.  
  3. KeyPair keyPair = keyPairGenerator.generateKeyPair();  

  2. 获取公钥/私钥:

Java代码 
  1. PublicKey publicKey = keyPair.getPublic();  
  2. PrivateKey privateKey = keyPair.getPrivate();  

  3. 服务器数据使用私钥加密:

Java代码 
  1. Cipher cipher = Cipher.getInstance("rsa");  
  2. cipher.init(Cipher.ENCRYPT_MODE, privateKey, new SecureRandom());  
  3. byte[] cipherData = cipher.doFinal(plainText.getBytes());  

  4. 用户使用公钥解密:

Java代码 
  1. cipher.init(Cipher.DECRYPT_MODE, publicKey, new SecureRandom());  
  2. byte[] plainData = cipher.doFinal(cipherData);  

  5. 服务器根据私钥和加密数据生成数字签名:

Java代码 
  1. Signature signature  = Signature.getInstance("MD5withRSA");  
  2. signature.initSign(privateKey);  
  3. signature.update(cipherData);  
  4. byte[] signData = signature.sign();  

  6. 用户根据公钥、加密数据验证数据是否被修改过:

Java代码 
  1. signature.initVerify(publicKey);  
  2. signature.update(cipherData);  
  3. boolean status = signature.verify(signData);  

  7. RSA算法代码demo:尴尬

Java代码 
  1. /** 
  2.  * 功能简述: 使用RSA非对称加密/解密. 
  3.  * @throws Exception 
  4.  */  
  5. @Test  
  6. public void test04() throws Exception {  
  7.     String plainText = "Hello , world !";  
  8.       
  9.     KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("rsa");  
  10.     keyPairGenerator.initialize(1024);  
  11.     KeyPair keyPair = keyPairGenerator.generateKeyPair();  
  12.       
  13.     PublicKey publicKey = keyPair.getPublic();  
  14.     PrivateKey privateKey = keyPair.getPrivate();  
  15.       
  16.     Cipher cipher = Cipher.getInstance("rsa");  
  17.     SecureRandom random = new SecureRandom();  
  18.       
  19.     cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);  
  20.     byte[] cipherData = cipher.doFinal(plainText.getBytes());  
  21.     System.out.println("cipherText : " + new BASE64Encoder().encode(cipherData));  
  22.     //gDsJxZM98U2GzHUtUTyZ/Ir/NXqRWKUJkl6olrLYCZHY3RnlF3olkWPZ35Dwz9BMRqaTL3oPuyVq  
  23.     //sehvHExxj9RyrWpIYnYLBSURB1KVUSLMsd/ONFOD0fnJoGtIk+T/+3yybVL8M+RI+HzbE/jdYa/+  
  24.     //yQ+vHwHqXhuzZ/N8iNg=  
  25.   
  26.     cipher.init(Cipher.DECRYPT_MODE, publicKey, random);  
  27.     byte[] plainData = cipher.doFinal(cipherData);  
  28.     System.out.println("plainText : " + new String(plainData));  
  29.     //Hello , world !  
  30.       
  31.     Signature signature  = Signature.getInstance("MD5withRSA");  
  32.     signature.initSign(privateKey);  
  33.     signature.update(cipherData);  
  34.     byte[] signData = signature.sign();  
  35.     System.out.println("signature : " + new BASE64Encoder().encode(signData));  
  36.     //ADfoeKQn6eEHgLF8ETMXan3TfFO03R5u+cQEWtAQ2lRblLZw1DpzTlJJt1RXjU451I84v3297LhR  
  37.     //co64p6Sq3kVt84wnRsQw5mucZnY+jRZNdXpcbwh2qsh8287NM2hxWqp4OOCf/+vKKXZ3pbJMNT/4  
  38.     ///t9ewo+KYCWKOgvu5QQ=  
  39.   
  40.     signature.initVerify(publicKey);  
  41.     signature.update(cipherData);  
  42.     boolean status = signature.verify(signData);  
  43.     System.out.println("status : " + status);  
  44.     //true  
  45. }  

 

        Ok,这个blog的内容够长的了,还是在下一篇博客中对加密解密封装成一个工具类吧,然后简单介绍一下Commons Codec对BASE64的扩展支持!微笑

 

1
0
分享到:
评论
4 楼 greatwqs 2019-03-14  
  
3 楼 Zihuatanejo50 2016-05-26  
总结的挺全面的 
2 楼 fanit 2016-04-07  
谢谢博主,学习了
1 楼 琨玉秋霜 2015-08-07  

相关推荐

    node-v8.1.4-linux-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    麦肯锡-xxKPI方案gl.ppt

    麦肯锡-xxKPI方案gl.ppt

    基于Transformer模型构建的聊天机器人python源码+运行说明.zip

    一、简介 基于Transformer模型构建的聊天机器人,可实现日常聊天。 二、系统说明 2.1 功能介绍 使用者输入文本后,系统可根据文本做出相应的回答。 2.2 数据介绍 * 百度中文问答 WebQA数据集 * 青云数据集 * 豆瓣数据集 * chatterbot数据集 由于数据集过大,因此不会上传,如有需要可以在issue中提出。 2.3. 模型介绍(v1.0版本) 基于Transformer模型,使用Python中的keras-transformer包。 训练的参数文件没有上传,如有需要可在issue中提出。 三、注意事项 * keras-transformer包需要自行安装:`pip install keras-transformer`。 * 如果需要实际运行,参数文件放在`ModelTrainedParameters`文件下;`ListData`文件下包含了已经处理好的字典等数据,不需要修改,直接运行Main.py即可。 * 如果需要自行训练,将数据集文件放在`DataSet`文件下。 * `HyperParameters.py`文件中包含了系统所需

    -大学生心理健康数据集

    -大学生心理健康数据集

    拾放机构3D 拾放机构3D

    拾放机构

    遥控器的飞行控制操作、视频回传、数据透传以及获取无人机的飞行参数等功能

    APP基于DJI Mobile SDK,实现了获取和释放遥控器的控制权限、模拟遥控器的飞行控制操作、视频回传、数据透传以及获取无人机的飞行参数等功能。.zip

    SITRANS LG240 操作说明书

    SITRANS LG240 操作说明书

    基于matlab实现的matlab中的通信工具箱中simulink搭建直接序列扩频系统并进行仿真.rar

    基于matlab实现的matlab中的通信工具箱中simulink搭建直接序列扩频系统并进行仿真.rar

    基于无人机吊舱单目相机的目标定位算法与C++代码实现.zip

    无人机最强算法源码,易于部署和学习交流使用

    360qx无人机app.zip

    无人机最强源码,无人机算法,易于部署和学习交流使用

    无人机降落TRT版本.zip

    无人机最强算法源码,易于部署和学习交流使用

    node-v9.0.0-linux-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    ISO 19453-4-2018.pdf

    ISO 19453-4-2018.pdf

    该项目是一个无人机地面站,通过visual studio编译.zip

    无人机最强算法源码,易于部署和学习交流使用

    node-v10.15.1-linux-ppc64le.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v8.14.0-linux-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v6.11.3-x86.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

Global site tag (gtag.js) - Google Analytics