热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

廖雪峰Java10加密与安全4加密算法1对称加密算法

1.对称加密算法加密和解密使用同一个密钥,例如WinRAR。WinRAR在对文件进行打包的时候,可以设置一个密码,在解压的时候需要使用同样

1.对称加密算法

加密和解密使用同一个密钥,例如WinRAR。

  • WinRAR在对文件进行打包的时候,可以设置一个密码,在解压的时候需要使用同样的密码才能正确的解压。
  • 加密:encrypt(key,message) -> s
  • 解密:decrypt(key,s) -> message
    1418970-20190510221122326-1843725781.png
算法密钥长度(决定加密的强度)工作模式(参数)填充模式(格式的选择)
DES56/64ECB, CBC, PCBC, CTR...NoPadding, PKCS5Padding
AES128/192/256ECB,CBC,PCBC,CTR...NoPadding,PKCS5Padding, PKCS7Padding
IDEA128ECBPKCS5Padding, PKCS7Padding

JDK提供的算法并没有包括所有的工作模式和填充模式,但我们通常只需要挑选常用的模式使用就可以了。
DES因为密钥过短,可以在短时间内被暴力破解,所以并不安全。

2.AES/ECB

package com.testList;import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Base64;public class SplitString {//指定算法为AES,工作模式为ECB,填充模式为PKCS5Paddingstatic final String CIPHER_NAME = "AES/ECB/PKCS5Padding";//加密public static byte[] encrypt(byte[] key,byte[] input) throws GeneralSecurityException{//传入算法、工作模式、填充模式,创建Cipher示例Cipher cipher = Cipher.getInstance(CIPHER_NAME);//将一个byte数组,转化为一个AES的keySecretKeySpec secretKeySpec = new SecretKeySpec(key,"AES");//初始化:采用加密模式,并传入keycipher.init(Cipher.ENCRYPT_MODE,secretKeySpec);//通过doFinal传入input数组获取加密后的byte数组return cipher.doFinal(input);}//解密public static byte[] decrypt(byte[] key,byte[] input) throws GeneralSecurityException{//传入算法、工作模式、填充模式,创建Cipher示例Cipher cipher = Cipher.getInstance(CIPHER_NAME);//将byte数组,转化为一个AES的keySecretKeySpec secretKeySpec = new SecretKeySpec(key,"AES");//初始化:采用解密模式,并传入keycipher.init(Cipher.DECRYPT_MODE,secretKeySpec);//通过doFinal传入input数组获取加密后的byte数组return cipher.doFinal(input);}public static void main(String[] args) throws Exception{String message = "Hello,world!encrypted using AES!";System.out.println(message);//密钥为128位,需要传入128/8=16个byte的字符串byte[] key = "1234567890abcdef".getBytes("utf-8");byte[] input = message.getBytes(StandardCharsets.UTF_8);byte[] encrypted = encrypt(key,input);//把秘闻转化为61位编码打印System.out.println("Encrypted data:"+Base64.getEncoder().encodeToString(encrypted));byte[] decrypted = decrypt(key,encrypted);//将解密后的数组还原为字符串System.out.println("Decrypted data:"+new String(decrypted,"utf-8"));}
}

1418970-20190512165540313-1585280517.png

3.AES/CBC

package com.testList;import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.Base64;public class AES_CBC {//指定算法为为AES,工作模式为CBC,填充模式为PKCS5Paddingstatic final String CIPHER_NAME = "AES/CBC/PKCS5Padding";//加密public static byte[] encrypt(byte[] key,byte[] input) throws GeneralSecurityException{//传入算法、工作模式、填充模式,创建Cipher实例Cipher cipher = Cipher.getInstance(CIPHER_NAME);//传入key数组,获取SecretKeySpec的实例SecretKeySpec keySpec = new SecretKeySpec(key,"AES");//创建SecureRandom实例,用于获取随机数SecureRandom sr = SecureRandom.getInstanceStrong();//获取一个16位字节的数组byte[] iv = sr.generateSeed(16);//传入随机数组,获取IVParameterSpec实例IvParameterSpec ivps = new IvParameterSpec(iv);//初始化:指定加密模式,并传入SecretKeySpec实例keySpec、IvParameterSpec实例ivpscipher.init(Cipher.ENCRYPT_MODE,keySpec,ivps);//通过doFinal传入input数组,获取加密后的byte数组byte[] data = cipher.doFinal(input);//将iv,data一并返回return join(iv,data);}public static byte[] join(byte[] bs1,byte[] bs2){byte[] r = new byte[bs1.length+bs2.length];System.arraycopy(bs1,0,r,0,bs1.length);System.arraycopy(bs2,0,r,bs1.length,bs2.length);return r;}public static byte[] decrypt(byte[] key,byte[] input) throws GeneralSecurityException{//将input数组拆分为iv,databyte[] iv = new byte[16];byte[] data = new byte[input.length-16];System.arraycopy(input,0,iv,0,16);System.arraycopy(input,16,data,0,data.length);//传入算法、工作模式、填充模式,创建Cipher实例Cipher cipher = Cipher.getInstance(CIPHER_NAME);//传入key数组,获取AES加密后的SecretKeySpec类型实例SecretKeySpec keySpec = new SecretKeySpec(key,"AES");//获取IvParameter实例ivpsIvParameterSpec ivps = new IvParameterSpec(iv);//初始化:指定解密模式,并传入SecretKeySpec实例,IvParameterSpec实例cipher.init(Cipher.DECRYPT_MODE,keySpec,ivps);//返回解密后的数组return cipher.doFinal(data);}public static void main(String[] args) throws Exception {String message = "Hello,world!encryptd using AES!";System.out.println("Message:"+message);byte[] key = "1234567890abcefg".getBytes("utf-8");byte[] data = message.getBytes(StandardCharsets.UTF_8);byte[] encrypted = encrypt(key,data);System.out.println("Encrypt data:"+Base64.getEncoder().encodeToString(encrypted));byte[] decryptd = decrypt(key,encrypted);System.out.println("Decrypted data:"+new String(decryptd,"utf-8"));}
}

1418970-20190512184745899-271931943.png

4.AES/ECB使用256位加密

import jdk.nashorn.internal.runtime.ECMAException;import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Base64;public class AES256_ECB {static final String CIPHER_NAME = "AES/ECB/PKCS5Padding";public static byte[] encrypt(byte[] key,byte[] input) throws GeneralSecurityException {Cipher cipher = Cipher.getInstance(CIPHER_NAME);SecretKeySpec keySpec = new SecretKeySpec(key,"AES");cipher.init(Cipher.ENCRYPT_MODE,keySpec);return cipher.doFinal(input);}public static byte[] decrypt(byte[] key,byte[] input) throws GeneralSecurityException{Cipher cipher = Cipher.getInstance(CIPHER_NAME);SecretKeySpec keySpec = new SecretKeySpec(key,"AES");cipher.init(Cipher.ENCRYPT_MODE,keySpec);return cipher.doFinal(input);}public static void main(String[] args) throws Exception {String message = "Hello world!encrypted using AES!";System.out.println(message);byte[] key = "1234567890abcdef1234567890abcdef".getBytes("utf-8");byte[] data = message.getBytes(StandardCharsets.UTF_8);byte[] encrypted = encrypt(key,data);System.out.println(Base64.getEncoder().encodeToString(encrypted));byte[] decrypted = decrypt(key,encrypted);System.out.println(new String(decrypted,"utf-8"));}
}

1418970-20190513184244804-128553369.png
问题:256位加密执行失败
1418970-20190513184137496-240293325.png
搜索jdk jce policy,下载jar包,
window:将下载的jar包复制到jdk/jre/lib/security和jdk/lib/security目录下。
Mac:

#查看Java目录
which java
#寻找jre/lib/security目录
find . -name lcoal_policy.jar

如我的目录是:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/security。将下载的jar包复制到该文件。
再次运行,不再报错

5.总结:

  • 对称加密算法使用同一个密钥进行加密和解密
  • 常用算法:DES/AES/IDEA等
  • 密钥长度由算法设计决定给,AES的密钥长度是128/192/256
  • 使用256位加密需要修改JDK的policy文件
  • 使用对称加密算法需要指定:算法名称/工作模式/填充模式

转:https://www.cnblogs.com/csj2018/p/10847053.html



推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
author-avatar
许琼博762375
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有