JAVA DES 加密解密、生成秘钥 详解

JAVA 实现DES 加密解密、生成秘钥

JAVA 加密使用的库是Cipher

javax.crypto.Cipher 是java原生的类库,用来做加密解密的。

官网描述

https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html#method.detail/

此类提供用于加密和解密的密码算法的功能。它构成了Java加密扩展(JCE)框架的核心。

1、getInstance 创建Cipher实例

A transformation is a string that describes the operation 
(or set of operations) to be performed on the given input, 
to produce some output. A transformation always includes 
the name of a cryptographic algorithm (e.g., AES), and may
 be followed by a feedback mode and padding scheme.

A transformation is of the form:

"algorithm/mode/padding" or
"algorithm"

(in the latter case, provider-specific default values for
 the mode and padding scheme are used). For example, the 
 following is a valid transformation:

     Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");

在这里插入图片描述

创建实例两种方法:

第一种创建方式
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");

参数由“/” 隔开

algorithm 算法
mode 模式
padding 填充
第二种创建方式
Cipher c = Cipher.getInstance("RSA");
algorithm 算法
算法支持
Every implementation of the Java platform is required to support the following standard Cipher transformations with the keysizes in parentheses:
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)

可以看出Cipher 支持AES,DES,DESede,RSA

这里列举了全部支持的Algorithm Mode Padding
https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher

2、init 初始化秘钥

可以从证书、Key来初始化Cipher
在这里插入图片描述

使用给定参数初始化此密码。

针对以下四个操作之一初始化密码:加密,解密,密钥包装或密钥解包,具体取决于的值opmode。

如果证书的类型为X.509,并且密钥使用 扩展字段标记为关键,并且密钥使用 扩展字段的值表示证书中的公钥及其对应的私钥不应用于 抛出opmode一个以表示的操作InvalidKeyException。

如果此密码需要任何不能从给定证书中的公钥派生的算法参数,则如果正在对其进行加密或加密初始化,则该基础密码实现应自行生成所需的参数(使用提供程序特定的默认值或随机值)。密钥包装, InvalidKeyException如果正在初始化以进行解密或密钥解包,则引发。可以使用getParameters或 getIV(如果参数为IV)检索生成的参数 。

如果此密码要求无法从输入参数中得出的算法参数,并且没有合理的提供程序特定的默认值,则初始化必然会失败。

如果此密码(包括其基础反馈或填充方案)需要任何随机字节(例如,用于参数生成),它将使用SecureRandom 安装的最高优先级提供程序作为随机源来获取它们 。(如果没有安装的提供程序提供SecureRandom的实现,则将使用系统提供的随机性源。)

请注意,在初始化Cipher对象时,它将丢失所有先前获取的状态。换句话说,初始化Cipher等效于创建该Cipher的新实例并将其初始化。
参数:
opmode 参数可选:
ENCRYPT_MODE,DECRYPT_MODE, WRAP_MODE或UNWRAP_MODE

key 可选
DHPrivateKey, DHPublicKey, DSAPrivateKey, DSAPublicKey, ECPrivateKey, ECPublicKey, PBEKey, PrivateKey, PublicKey, RSAMultiPrimePrivateCrtKey, RSAPrivateCrtKey, RSAPrivateKey, RSAPublicKey, SecretKey

InvalidKeyException 抛出情况:
如果给定密钥不适合初始化此密码;
或者需要无法从给定密钥确定的算法参数;
或者给定密钥的密钥大小超过最大允许密钥大小;
通过Key来创建
//获取key
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
DESKeySpec keySpec = new DESKeySpec(secretKey.getBytes());
Key key = keyFactory.generateSecret(keySpec);
//初始化
cipher.init(Cipher.DECRYPT_MODE, key);

证书的方式就不实验了

3、doFinal 完成加密 、解密数据

在这里插入图片描述

参数:

byte[] input 输入的数据

4、方法封装

秘钥获取
/**
* @Title: generateKey
* @Description: 生成SecretKey
* @param key字符串
* @return SecretKey
* @throws
*/
private static SecretKey generateKey(String secretKey)
		throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
	SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
	DESKeySpec keySpec = new DESKeySpec(secretKey.getBytes());
	keyFactory.generateSecret(keySpec);
	return keyFactory.generateSecret(keySpec);
}
加密
/**
	* @Title: encrypt
	* @Description: 加密方法
	* @param 
	* @return byte[]
	* @throws
	*/
	public static byte[] encrypt(byte[] content, byte[] keyBytes) throws Exception{
		try {

			DESKeySpec keySpec = new DESKeySpec(keyBytes);
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
			SecretKey key = keyFactory.generateSecret(keySpec);
			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_ECB);
//			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
//			IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));
//			cipher.init(Cipher.ENCRYPT_MODE, key ,iv );
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] result = cipher.doFinal(content);
			return result;
		}catch(Exception e) {
			e.printStackTrace();
			throw new Exception("DES加密异常:"+e.getMessage());
		}
	}
解密
	/**
	* @Title: decrypt
	* @Description: 解密
	* @param content 解密内容
	* @param key 密key
	* @return String
	* @throws
	*/
	public static String decrypt(String content, String key) throws Exception {
		try {
			
//			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
//			IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));
//			cipher.init(Cipher.DECRYPT_MODE, generateKey(key),iv);
			
			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_ECB);
			cipher.init(Cipher.DECRYPT_MODE, generateKey(key));
			byte[] buf = cipher.doFinal(hexStr2Bytes(content));
			return new String(buf, CHARSET);
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("DES解密异常:" + e.getMessage());
		}
	}

注意事项

1、前端和后端的 algorithm/mode/padding 需要一致
2、秘钥的 String 编码方式要注意一致

扩展

1、可以看到这对应的AES和RSA 各种加密方式都支持,可以直接将秘钥初始化成其他的算法就完成了更换。
2、EBC为默认的模式,前端库中的默认模式为CBC,因为EBC在很多时候评估并不太安全,所以两边都使用默认的时候就会发现怎么都对不上,所以需要指定对应的方式。
3、https://docs.oracle.com/javase/8/docs/api/ 详细API可以直接查看官网

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忙碌的菠萝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值