Java 对称加密
最近在做一个用户 token 功能,学习了加密相关 AES/DES、RSA 等。其中涉及一个对称和非对称加密问题。对称加密虽然没有非对称加密那样安全性高,但好处是加密速度快,但某些场合还是可以选择使用的,例如当下的用户认知机制,它是基于 token 无状态的,每次请求过来都会认证一次,这样就必须要比较高速度的加密解密运算,于是我们选择了 AES 加密方式。
下面是对称加密的工具类,完全可以不依赖其他三方 jar 包。不过有个 base64 方法我封装起来了(下面会补充)。
- import java.nio.charset.StandardCharsets;
- import java.security.InvalidKeyException;
- import java.security.NoSuchAlgorithmException;
- import java.security.SecureRandom;
- import javax.crypto.BadPaddingException;
- import javax.crypto.Cipher;
- import javax.crypto.IllegalBlockSizeException;
- import javax.crypto.KeyGenerator;
- import javax.crypto.NoSuchPaddingException;
- import javax.crypto.SecretKey;
- import com.ajaxjs.util.Encode;
- /**
- * 对称算法
- * @author admin
- *
- */
- public class SymmetricCipher {
- public SymmetricCipher() {}
- public SymmetricCipher(String ALGORITHM, int keySize) {
- this.ALGORITHM = ALGORITHM;
- this.keySize = keySize;
- }
- /**
- * DES = 56 | AES = 128
- */
- private int keySize = 128;
- /**
- * 加密算法,可以 DES | AES
- */
- private String ALGORITHM = "AES";
- /**
- * 加密
- *
- * @param str
- * 要加密的内容
- * @param key
- * 密钥
- * @return 加密后的内容
- */
- public String encrypt(String str, String key) {
- // 这里要设置为utf-8不然内容中如果有中文和英文混合中文就会解密为乱码
- return doCipher(true, key, str, str.getBytes(StandardCharsets.UTF_8));
- }
- /**
- * 解密
- *
- * @param str
- * 要解密的内容
- * @param key
- * 密钥
- * @return 解密后的内容
- */
- public String decrypt(String str, String key) {
- return doCipher(false, key, str, Encode.base64DecodeAsByte(str));
- }
- private String doCipher(boolean isENCRYPT_MODE, String key, String str, byte[] bytes) {
- Cipher cipher = null;
- try {
- cipher = Cipher.getInstance(ALGORITHM);
- cipher.init(isENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, generateKey(key));
- } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException e) {
- e.printStackTrace();
- return null;
- }
- byte[] buf;
- try {
- // 为了防止解密时报javax.crypto.IllegalBlockSizeException: Input length must
- // be multiple of 8 when decrypting with padded cipher异常,
- // 不能把加密后的字节数组直接转换成字符串
- buf = cipher.doFinal(bytes);
- } catch (IllegalBlockSizeException | BadPaddingException e) {
- e.printStackTrace();
- return null;
- }
- return isENCRYPT_MODE ? Encode.base64Encode(buf) : Encode.byte2String(buf);
- }
- /**
- * 获得密钥对象
- *
- * @param key
- * 密钥
- * @return 密钥对象
- */
- private SecretKey generateKey(String key) {
- SecureRandom secureRandom;
- KeyGenerator kg;
- try {
- secureRandom = SecureRandom.getInstance("SHA1PRNG");
- secureRandom.setSeed(key.getBytes());
- kg = KeyGenerator.getInstance(ALGORITHM);
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- return null;
- }
- kg.init(keySize, secureRandom);
- return kg.generateKey();// 生成密钥
- }
- final static SymmetricCipher AES = new SymmetricCipher();
- final static SymmetricCipher DES = new SymmetricCipher("DES", 56);
- /**
- * AES 加密
- *
- * @param str
- * 要加密的内容
- * @param key
- * 密钥
- * @return 加密后的内容
- */
- public static String AES_Encrypt(String str, String key) {
- return AES.encrypt(str, key);
- }
- /**
- * AES 解密
- * @param str
- * @param key
- * @return
- */
- public static String AES_Decrypt(String str, String key) {
- return AES.decrypt(str, key);
- }
- }
使用方法如下
- import org.junit.Test;
- import static org.junit.Assert.*;
- import com.ajaxjs.user.password.SymmetricCipher;
- public class TestPassword {
- String input = "cy11Xlbrmzyh:604:301:1353064296";
- String key = "37d5aed075525d4fa0fe635231cba447";
- @Test
- public void testEncryption() {
- String EncryptedPassword = SymmetricCipher.AES_Encrypt(input, key);
- // System.out.println("EncryptedPassword::" +EncryptedPassword);
- assertEquals(input, SymmetricCipher.AES_Decrypt(EncryptedPassword, key));
- }
- }
Base64 编码解码方法
- package com.ajaxjs.util;
- import java.io.IOException;
- import java.io.UnsupportedEncodingException;
- import java.net.URLDecoder;
- import java.net.URLEncoder;
- import java.nio.charset.StandardCharsets;
- import sun.misc.BASE64Decoder;
- import sun.misc.BASE64Encoder;
- /**
- * 字符串的编码、解密
- * @author admin
- *
- */
- public class Encode {
- /**
- * 字节转编码为 字符串( UTF-8 编码)
- *
- * @param bytes
- * 输入的字节数组
- * @return 字符串
- */
- public static String byte2String(byte[] bytes) {
- return new String(bytes, StandardCharsets.UTF_8);
- }
- /**
- * 字符串转为 UTF-8 编码的字符串
- *
- * @param str
- * 输入的字符串
- * @return UTF-8 字符串
- */
- public static String byte2String(String str) {
- return byte2String(str.getBytes());
- }
- /**
- * 将 URL 编码的字符还原,默认 UTF-8 编码
- *
- * @param str
- * 已 URL 编码的字符串
- * @return 正常的 Java 字符串
- */
- public static String urlDecode(String str) {
- try {
- return URLDecoder.decode(str, StandardCharsets.UTF_8.toString());
- } catch (UnsupportedEncodingException e) {
- return null;
- }
- }
- /**
- * 将字符进行 URL 编码,默认 UTF-8 编码
- *
- * @param str
- * 正常的 Java 字符串
- *
- * @return 已 URL 编码的字符串
- */
- public static String urlEncode(String str) {
- try {
- return URLEncoder.encode(str, StandardCharsets.UTF_8.toString());
- } catch (UnsupportedEncodingException e) {
- return null;
- }
- }
- /**
- * url 网址中文乱码处理。
- * 如果 Tomcat 过滤器设置了 utf-8 那么这里就不用重复转码了
- *
- * @param str
- * 通常是 url Query String 参数
- * @return 中文
- */
- public static String urlChinese(String str) {
- return byte2String(str.getBytes(StandardCharsets.ISO_8859_1));
- }
- /**
- * BASE64 编码
- * @param bytes输入的字节数组
- * @return 已编码的字符串
- */
- public static String base64Encode(byte[] bytes) {
- return new BASE64Encoder().encode(bytes);
- }
- /**
- * BASE64 编码
- *
- * @param str
- * 待编码的字符串
- * @return 已编码的字符串
- */
- public static String base64Encode(String str) {
- return base64Encode(str.getBytes());
- }
- public static byte[] base64DecodeAsByte(String str) {
- BASE64Decoder decoder = new BASE64Decoder();
- try {
- return decoder.decodeBuffer(str);
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- }
- }
- /**
- * BASE64 解码 这里需要强制捕获异常。
- * 中文乱码:http://s.yanghao.org/program/viewdetail.php?i=54806
- *
- * @param str
- * 已解码的字符串
- * @return 已解码的字符串
- */
- public static String base64Decode(String str) {
- return byte2String(base64DecodeAsByte(str));
- }
- }
Java 对称加密的更多相关文章
- java对称加密(AES)
java对称加密(AES) 博客分类: Java javaAES对称加密 /** * AESHelper.java * cn.com.songjy.test * * Function: TODO * ...
- PHP、Java对称加密中的AES加密方法
PHP AES加密 <?php ini_set('default_charset','utf-8'); class AES{ public $iv = null; public $key = n ...
- AES —— JAVA中对称加密和解密
package demo.security; import java.io.IOException; import java.io.UnsupportedEncodingException; impo ...
- Java和.NET使用DES对称加密的区别
Java和.NET的系统类库里都有封装DES对称加密的实现方式,但是对外暴露的接口却各不相同,甚至有时会让自己难以解决其中的问题,比如Java加密后的结果在.NET中解密不出来等,由于最近项目有跨Ja ...
- Java安全之对称加密、非对称加密、数字签名
原文地址: http://blog.csdn.net/furongkang/article/details/6882039 Java中加密分为两种方式一个是对称加密,另一个是非对称加密.对称加密是因为 ...
- 对称加密详解,以及JAVA简单实现
(原) 常用的加密有3种 1.正向加密,如MD5,加密后密文固定,目前还没办法破解,但是可以能过数据库撞库有一定概率找到,不过现在一般用这种方式加密都会加上盐值. 2.对称加密,通过一个固定的对称密钥 ...
- Java加密与解密笔记(二) 对称加密
前面的仅仅是做了编码或者摘要,下面看看真正的加密技术. DES public class DESUtil { static final String ALGORITHM = "DES&quo ...
- java的AES对称加密和解密,有偏移量
import java.math.BigDecimal; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; i ...
- java中的数据加密2 对称加密
对称加密 也叫私钥加密. 采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密. 需要对加密和解密使用相同密钥的加密算法.由于其速度快,对 ...
随机推荐
- LeetCode:比较含退格字符串【844】
LeetCode:比较含退格字符串[844] 题目描述 给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果. # 代表退格字符. 示例 1: 输入:S = ...
- Kattis - fence2【二分法】
Kattis - fence2[二分法] 题意 有一个农夫需要建造一个 N - 1 米长的篱笆,需要 N 根柱子,然后有 K 根 柱子 需要将这 K 根柱子 切成 N 段 然后 要尽量保证这 N 段柱 ...
- Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) A - Neverending competitions
地址:http://codeforces.com/contest/765/problem/A 题目: A. Neverending competitions time limit per test 2 ...
- Unity,如何阻塞当前函数一段时间
public class Example : MonoBehaviour { IEnumerator Example() { print(Time.time); ); print(Time.time) ...
- Python面试题之Super函数
这是个高大上的函数,在python装13手册里面介绍过多使用可显得自己是高手 23333. 但其实他还是很重要的. 简单说, super函数是调用下一个父类(超类)并返回该父类实例的方法. 这里的下一 ...
- Sybase:SAP IQ学习笔记
Sybase:SAP IQ学习笔记 -- 启动IQ管理 >> start_iq -n utility_db -n utility_db >> dbisql -c "u ...
- Percona-Server-5.7.16 启动错误
基于:percona-server-5.7.16 启动报错: [root@monitor mysql]# ./bin/mysqld_safe --defaults-file=/data/config ...
- java中最常用jar包的用途
jar包用途 axis.jarSOAP引擎包commons-discovery-0.2.jar用来发现.查找和实现可插入式接口,提供一些一般类实例化.单件的生命周期管理的常用方法.jaxrpc.jar ...
- 记一次网卡报错ERROR,some other host already uses address
提示IP地址冲突,但是此IP确实没有被其他Server占用 解决如下: 编辑此文件 搜索arping 将下面几行注释掉 保存退出 激活网卡 此时IP地址已生效 下面是我的系统版本 (一般应该不会出现这 ...
- 利用MacBookPro入侵无线网络
目前无线网络的加密方式主要有WEP,WPA/WPA2.这是最常看到的加密方式,最近由于需要,专门去研究了一下如何入侵无线网络. 1.入侵WEP加密的无线网络 WEP加密方式现在已经很不安全了,因为只要 ...