Java 加解密类的功能用法介绍及实际项目中数据加密解密的解决办法

前段时间公司Android项目的网络请求模块进行了重构,从单纯使用HttpClient切换到了使用Retrofit框架,在重构过程中重新梳理了一下数据加密解密的方式与过程,发现现在的加解密解决办法简单有效,在学习的过程中接触了数据加密时需要用到的几个类,算是我的知识盲区吧,现在拿出来和大家分享一下,顺便记录。

     java为我们提供了完整的数据加解密,密钥生成的类,我们只要确定我们的加密算法和需要加密的数据就可以调用方法进行加密,得到规范的加密后的数据,解密也同样如此。

接下来蛋蛋介绍一下对称加密和非对称加密(记住,这和加密算法没有关系),对称加密是指加密和解密都使用同一个密钥,比如说你的密钥是1,我们用1进行加密,那么获取我数据的人就要用1进行解密。加密算法是指我的数据和我的密钥(1)进行了怎样的操作,比如说我把我的数据拆成字节的形式,每个字节都加上1,那么解密的时候就要每个字节都减去1从而获得正确的数据,这个方法就叫做加密算法,当然实际生产中加密算法复杂的多且多种多样。非对称加密是指加密的密钥和解密的密钥是不同的,分为公钥和私钥,私钥只由一方保管,公钥公布给需要与私钥持有者进行数据交互的人,如果数据是由公钥加密的那么必须要用私钥进行解密,反之私钥加密必须用公钥解密。比较著名的非对称加密算法是RSA,在实际生产中使用的也是这个加密算法。在项目中使用的是这两种加密方式结合的方法,这点稍后介绍,我们先来看一下在java中怎样通过调用系统的方法实现上述两种加密方法。

     首先是SecretKeySpec类,它负责根据一个字符数组构造一个密钥,我们约定好的密钥(也就是一个字符数组)不能直接作为加密Key来使用,必须要生成这样一个对象。构造方法是SecretKeySpec(byte[] key, String algorithm),第一个参数是我的约定好的key,第二个参数是加密方法,这里我们使用DESede加密算法。

private static final String Algorithm = "DESede"

// 生成密钥
SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);

// 加密
Cipher c1 = Cipher.getInstance(Algorithm);
c1.init(Cipher.ENCRYPT_MODE, deskey);

 从代码我们可以看到,我们的加密类Cipher(之后会介绍到,这里只要知道我们使用它来加密数据即可)初始化需要SecertKeySpec的对象,那么SecertKeySpec的对象是什么呢?它是一种密钥规范(底层可使用的密钥材料),我们的密钥材料(字符数组)不能直接使用,我们需要将它转换为底层可使用的密钥对象(材料),SecertKeySpec的对象对于Cipher来讲就是透明的,可直接使用的。

     接下来我们介绍一下Cipher类,这个类负责通过给定的密钥和数据进行加解密从而得到我们需要的数据。我们先来关注一下Cipher的getInstance方法,getInstance方法传入的是一个字符串,这个字符串是此类把怎样把输入的数据转换为输出数据的方法的名称。说直白一点就是加密方法的名称。init方法有两个参数,第一个就是此对象加工数据的模式,第二个参数是我们刚刚生成的密钥对象。介绍几个MODE

public static final int <strong>DECRYPT_MODE   用于将 Cipher 初始化为解密模式的常量。</strong>

?
1
public static final int <strong>WRAP_MODE      用于将 Cipher 初始化为密钥包装模式的常量。</strong>
?
1
public static final int <strong>UNWRAP_MODE   用于将 Cipher 初始化为密钥解包模式的常量。</strong>
?
1
public static final int <strong>PUBLIC_KEY    用于表示要解包的密钥为“公钥”的常量。</strong>
?
1
public static final int <strong>PRIVATE_KEY   用于表示要解包的密钥为“私钥”的常量。</strong>
?
1
public static final int <strong>SECRET_KEY    用于表示要解包的密钥为“秘密密钥”

      这样我们加解密所需要的Cipher对象就初始化好了

return c1.doFinal(src);

之后将我们的数据(src)传入就可以等到我们需要的数据,无论是我们加密的数据还是我们解密的数据。这样一个简单的用来加密解密的Java类的调用就介绍完了。

    使用非对称加密方法加密数据时,我们还需使用X509EncodedKeySpec类,X509EncodedKeySpec类使用X.509标准作为密钥规范管理的编码格式。在使用公钥时我们需要用编码格式来表示公钥。

// 实例化X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
// 实例化KeyFactory对象,并指定DSA算法
KeyFactory keyFactory = KeyFactory.getInstance("DSA");//或者"RSA"
// 获得PublicKey对象
PublicKey publicKey = keyFactory.generatePublic(keySpec);

从代码来看,我们的公钥首先要转换为X509格式,之后使用KeyFactory生成密钥对象,这时我们可以指定使用的加密算法(和我们Cipher实例化时使用的加密算法保持一致)。这样生成的密钥对象就可以被Cipher使用了。

顺便提一下,Cipher实例化出入的参数不仅仅是算法名称还包括模式和填充。格式是“算法/模式/填充”(DES/OFB32/PKCS5Padding等)或单独传算法名称

至此我们加密解密使用的Java类就介绍完了。

接下来说一下我在实际成产中用到的加密方式。在项目中与服务端进行数据交互时使用了对称加密和非对称加密结合的方式,首先在本地随机生成一个24位的密钥(字符数组)之后用此密钥加密我要上传的数据,然后用服务端提供的公钥加密我的密钥,之后将加密的数据和加密的密钥都传给服务端,服务端先使用私钥解密得到我用来加密数据所使用的密钥,再用这个密钥解密数据,传给我的数据也用这个密钥进行加密。也就是说数据是使用对称加密方法加密的,对称加密的密钥是使用非对称加密的,这样做的好处是让数据更加安全,我每次用来加密数据的密钥都是随机称成的,保证了每次密钥都是不同的,这个密钥具有时效性,被第三方获破解后得到也不能使用。公钥也可以随时更换,当服务端发现私钥已经不安全了,可以换一对key,将新的公钥传给我。




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaAES加密解密是一种常用的对称加密算法,它可以将明文加密成密文,并且可以使用相同的密钥进行解密。在Java,常用的JavaAES加密解密实现方式有两种:一种是基于Java自带的Cipher类实现的,另一种是基于第三方库实现的。 如果使用Java自带的Cipher类,可以按照以下步骤实现JavaAES加密解密: 1. 生成密钥,可以使用KeyGenerator类生成密钥。 2. 创建Cipher对象,设置加密模式和填充方式。 3. 初始化Cipher对象,设置加密解密模式,以及密钥。 4. 调用Cipher的doFinal方法进行加密解密操作。 以下是JavaAES加密解密的代码示例: ```java import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import java.nio.charset.StandardCharsets; import java.security.NoSuchAlgorithmException; public class JavaAESTest { public static void main(String[] args) throws Exception { String plaintext = "Hello, World!"; //明文 String password = "123456"; //密钥 //生成密钥 SecretKey secretKey = getSecretKey(password); //加密 byte[] ciphertext = encrypt(plaintext.getBytes(StandardCharsets.UTF_8), secretKey); System.out.println("加密后:" + new String(ciphertext, StandardCharsets.UTF_8)); //解密 byte[] decrypted = decrypt(ciphertext, secretKey); System.out.println("解密后:" + new String(decrypted, StandardCharsets.UTF_8)); } private static SecretKey getSecretKey(String password) throws NoSuchAlgorithmException { //生成AES算法的KeyGenerator对象 KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(128); //指定密钥长度为128位 //生成一个128位的随机安全密钥 return keyGenerator.generateKey(); } private static byte[] encrypt(byte[] plaintext, SecretKey secretKey) throws Exception { //创建Cipher对象,设置加密模式和填充方式 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); //初始化Cipher对象 //加密并返回结果 return cipher.doFinal(plaintext); } private static byte[] decrypt(byte[] ciphertext, SecretKey secretKey) throws Exception { //创建Cipher对象,设置解密模式和填充方式 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secretKey); //初始化Cipher对象 //解密并返回结果 return cipher.doFinal(ciphertext); } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值