Android加密算法

来源:互联网 发布:百度人工智能研发 编辑:程序博客网 时间:2024/05/19 21:40

基本需求及概念

随着Internet网的广泛应用,信息安全问题日益突出,以数据加密技术为核心的信息安全技术也得到了极大的发展。目前的数据加密技术根据加密密钥类型可分私钥加密(对称加密)系统和公钥加密(非对称加密)系统。

对称加密算法是较传统的加密体制,通信双方在加/解密过程中使用他们共享的单一密钥,鉴于其算法简单和加密速度快的优点,目前仍然是主流的密码体制之一。最常用的对称密码算法是数据加密标准(DES)算法,但是由于DES密钥长度较短,已经不适合当今分布式开放网络对数据加密安全性的要求。最后,一种新的基于Rijndael算法对称高级数据加密标准AES取代了数据加密标准DES。非对称加密由于加/解密钥不同(公钥加密,私钥解密),密钥管理简单,也得到广泛应用。RSA是非对称加密系统最著名的公钥密码算法

AES算法

美国国家标准和技术研究所(NIST)经过三轮候选算法筛选,从众多的分组密码中选中Rijndael算法作为高级加密标准(AES)。Rijndael密码是一个迭代型分组密码,分组长度和密码长度都是可变的,分组长度和密码长度可以独立的指定为128比特,192比特或者256比特。AES的加密算法的数据处理单位是字节,128位的比特信息被分成16个字节,按顺序复制到一个4*4的矩阵中,称为状态(state),AES的所有变换都是基于状态矩阵的变换。

用Nr表示对一个数据分组加密的轮数(加密轮数与密钥长度的关系如表1所示)。在轮函数的每一轮迭代中,包括四步变换,分别是字节代换运算(ByteSub())、行变换(ShiftRows())、列混合(MixColumns())以及轮密钥的添加变换AddRoundKey()[3],其作用就是通过重复简单的非线形变换、混合函数变换,将字节代换运算产生的非线性扩散,达到充分的混合,在每轮迭代中引入不同的密钥,从而实现加密的有效性。

下面是三种不同类型的AES加密密钥分组大小与相应的加密轮数的对照表。加密开始时,输入分组的各字节按表2 的方式装入矩阵state中。如输入ABCDEFGHIJKLMNOP,则输入块影射到如表2的状态矩阵中。 
表1:

AES类型 密钥长度 分组长度 加密轮数 
AES-128 4字 4字 10 
AES-192 6字 4字 12 
AES-256 8字 4字 14

A E I M 
B F J N 
C G K O 
D H L P

1、字节代换运算(ByteSub())

字节代换运算是一个可逆的非线形字节代换操作,对分组中的每个字节进行,对字节的操作遵循一个代换表,即S盒。S盒由有限域 GF(28)上的乘法取逆和GF(2)上的仿射变换两步组成。 
2、行变换ShiftRows()

行变换是一种线性变换,其目的就是使密码信息达到充分的混乱,提高非线形度。行变换对状态的每行以字节为单位进行循环右移,移动字节数根据行数来确定,第0行不发生偏移,第一行循环右移一个字节,第二行移两个,依次类推。 
3、 列混合变换MixColumns()

列变换就是从状态中取出一列,表示成多项式的形式后,用它乘以一个固定的多项式a(x),然后将所得结果进行取模运算,模值为 x4+1。其中a(x)={03}x3+{02}x2+{01}x+{02}, 
这个多项式与x4+1互质,因此是可逆的。列混合变换的算术表达式为:s’(x)= a(x) s(x),其中, s(x)表示状态的列多项式。 
4、轮密钥的添加变换AddRoundKey() 
在这个操作中,轮密钥被简单地异或到状态中,轮密钥根据密钥表获得,其长度等于数据块的长度Nb。 
AES算法流程

对于发送方,它首先创建一个AES私钥,并用口令对这个私钥进行加密。然后把用口令加密后的AES密钥通过Internet发送到接收方。发送方解密这个私钥,并用此私钥加密明文得到密文,密文和加密后的AES密钥一起通过Internet发送到接收方。接收方收到后再用口令对加密密钥进行解密得到AES密钥,最后用解密后的密钥把收到的密文解密成明文。图7中是这个过程的实现流程。 
AES算法流程

这里写图片描述

RSA算法

RSA算法基本原理及流程

RSA是在1977年发明RSA密码系统的三个人的名字的首字母的缩写,他们是:Ron Rivest、Adi Shamir和Leonard Adleman。它是第一个公钥加密算法,在很多密码协议中都有应用,如SSL和S/MIME。RSA算法是基于大质数的因数分解的公匙体系。简单的讲,就是两个很大的质数,一个作为公钥,另一个作为私钥,如用其中一个加密,则用另一个解密。密钥长度从40到2048位可变,密钥越长,加密效果越好,但加密解密的开销也大。RSA算法可简单描述如下:

公开密钥:n=pq,(p,q为两个不同的很大的质数,p和q必须保密)将(p-1)和(q-1)相乘得到φ(n)选择一个整数e (1<e<φ(n))与φ(n)互质秘密密钥:d=e-1modφ(n),即计算一个数字d,使得它满足公式 de=1 modφ(n)加密:c=mc(mod n) 解密:m=cd(mod n),m为明文,c为密文。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

RSA算法实现流程

首先,接收方创建RSA密匙对,即一个公钥和一个私钥,公钥被发送到发送方,私钥则被保存在接收方。发送方在接收到这个公钥后,用该公钥对明文进行加密得到密文,然后把密文通过网络传输给接收方。接收方在收到它们后,用RSA私钥对收到的密文进行解密,最后得到明文 下面 是整个过程的实现流程。

这里写图片描述

AES与RSA相结合数据加密方案

RSA算法是公开密钥系统的代表,其安全性建立在具有大素数因子的合数,其因子分解困难这一法则之上的。Rijndael算法作为新一代的高级加密标准,运行时不需要计算机有非常高的处理能力和大的内存,操作可以很容易的抵御时间和空间的攻击,在不同的运行环境下始终能保持良好的性能。这使AES将安全,高效,性能,方便,灵活性集于一体,理应成为网络数据加密的首选。相比较,因为AES密钥的长度最长只有256比特,可以利用软件和硬件实现高速处理,而RSA算法需要进行大整数的乘幂和求模等多倍字长处理,处理速度明显慢于AES[5];所以AES算法加解密处理效率明显高于RSA算法。在密钥管理方面,因为AES算法要求在通信前对密钥进行秘密分配,解密的私钥必须通过网络传送至加密数据接收方,而RSA采用公钥加密,私钥解密(或私钥加密,公钥解密),加解密过程中不必网络传输保密的密钥;所以RSA算法密钥管理要明显优于AES算法。

从上面比较得知,由于RSA加解密速度慢,不适合大量数据文件加密,因此在网络中完全用公开密码体制传输机密信息是没有必要,也是不太现实的。AES加密速度很快,但是在网络传输过程中如何安全管理AES密钥是保证AES加密安全的重要环节。这样在传送机密信息的双方,如果使用AES对称密码体制对传输数据加密,同时使用RSA不对称密码体制来传送AES的密钥,就可以综合发挥AES和RSA的优点同时避免它们缺点来实现一种新的数据加密方案。

Android端 AES+RSA结合实践

基本要求

保证传输数据的安全性 
保证数据的完整性 
能够验证客户端的身份 
基本流程

Android端

  1. 服务器端(server)分别生成自己的RSA密钥对,并提供接口给Android客户端获取RSA公钥(rsaPublicKey)
  2. client生成AES密钥(aesKey)
  3. client使用自己的AES密钥(aesKey)对转换为json格式的请求明文数据(data)进行加密,得到加密后的请求数据encryptData
  4. client提供server提供的接口获取RSA公钥(rsaPublicKey)
  5. client使用获取RSA公钥(rsaPublicKey)对AES密钥(aesKey)进行加密,得到encryptAesKey
  6. client将encryptAesKey作为http请求头参数,将加密后的请求数据encryptData作为请求体一起传输给服务器端 
    服务器端

    1. server 响应client的http请求,读取http请求头。获得client传过来的加密后的AES密钥(encryptAesKey),读取http请求体,获得client传过来的加密后的请求数据(encryptData)。
    2. server使用自己的RSA私钥(rsaPrivateKey)对加密后的AES密钥(encryptAesKey)进行RSA解密,得到AES密钥(aesKey)
    3. 使用解密后的AES密钥(aesKey)对加密后的请求数据(encryptData),进行AES解密操作,得到解密后的请求数据(data),该数据为json格式
    4. 对解密后的请求数据(data)进行json解析,然后做相关的响应操作。

这里写图片描述

分享github上一个demon https://github.com/wustrive2008/aes-rsa-java

下面进入代码实战。

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

MessageDigest md5 = MessageDigest.getInstance(“md5”); 
2. 进行加密操作: 
byte[] cipherData = md5.digest(plainText.getBytes());

  1. 将其中的每个字节转成十六进制字符串:byte类型的数据最高位是符号位,通过和0xff进行与操作,转换为int类型的正整数。 
    Java代码 
    String toHexStr = Integer.toHexString(cipher & 0xff);
  2. 如果该正数小于16(长度为1个字符),前面拼接0占位:确保最后生成的是32位字符串。 
    Java代码 
    builder.append(toHexStr.length() == 1 ? “0” + toHexStr : toHexStr);
  3. 加密转换之后的字符串为:c0bb4f54f1d8b14caf6fe1069e5f93ad
  4. 完整的MD5算法应用如下所示:
Java代码 /**  * 功能简述: 测试MD5单向加密.  * @throws Exception  */  @Test  public void test01() throws Exception {      String plainText = "Hello , world !";      MessageDigest md5 = MessageDigest.getInstance("md5");      byte[] cipherData = md5.digest(plainText.getBytes());      StringBuilder builder = new StringBuilder();      for(byte cipher : cipherData) {          String toHexStr = Integer.toHexString(cipher & 0xff);          builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr);      }      System.out.println(builder.toString());      //c0bb4f54f1d8b14caf6fe1069e5f93ad  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

<二>. 使用BASE64进行加密/解密: 
使用BASE64算法通常用作对二进制数据进行加密,加密之后的数据不易被肉眼识别。严格来说,经过BASE64加密的数据其实没有安全性可言保密,因为它的加密解密算法都是公开的,典型的防菜鸟不防程序猿的呀。 经过标准的BASE64算法加密后的数据, 通常包含/、+、=等特殊符号,不适合作为url参数传递,幸运的是Apache的Commons Codec模块提供了对BASE64的进一步封装。 (参见最后一部分的说明) 
1. 使用BASE64加密: 
Java代码 
BASE64Encoder encoder = new BASE64Encoder(); 
String cipherText = encoder.encode(plainText.getBytes()); 
2. 使用BASE64解密: 
Java代码 
BASE64Decoder decoder = new BASE64Decoder(); 
plainText = new String(decoder.decodeBuffer(cipherText)); 
3. 完整代码示例: 
Java代码

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

<三>. 使用DES对称加密/解密: 
数据加密标准算法(Data Encryption Standard),和BASE64最明显的区别就是有一个工作密钥,该密钥既用于加密、也用于解密,并且要求密钥是一个长度至少大于8位的字符串。使用DES加密、解密的核心是确保工作密钥的安全性。叫 
1. 根据key生成密钥: 
Java代码

DESKeySpec keySpec = new DESKeySpec(key.getBytes());  SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("des");  SecretKey secretKey = keyFactory.generateSecret(keySpec);  
  • 1
  • 2
  • 3
  1. 加密操作: 
    Java代码
Cipher cipher = Cipher.getInstance("des");  cipher.init(Cipher.ENCRYPT_MODE, secretKey, new SecureRandom());  byte[] cipherData = cipher.doFinal(plainText.getBytes());  
  • 1
  • 2
  • 3
  1. 为了便于观察生成的加密数据,使用BASE64再次加密:
String cipherText = new BASE64Encoder().encode(cipherData);  
  • 1
 生成密文如下:PtRYi3sp7TOR69UrKEIicA== 
  • 1
  • 2

4. 解密操作: 
Java代码

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

<四>. 使用RSA非对称加密/解密: 
RSA算法是非对称加密算法的典型代表,既能加密、又能解密。和对称加密算法比如DES的明显区别在于用于加密、解密的密钥是不同的。使用RSA算法,只要密钥足够长(一般要求1024bit),加密的信息是不能被破解的。天真用户通过https协议访问服务器时,就是使用非对称加密算法进行数据的加密、解密操作的。 
服务器发送数据给客户端时使用私钥(private key)进行加密,并且使用加密之后的数据和私钥生成数字签名(digital signature)并发送给客户端。客户端接收到服务器发送的数据会使用公钥(public key)对数据来进行解密,并且根据加密数据和公钥验证数字签名的有效性,防止加密数据在传输过程中被第三方进行了修改。 
客户端发送数据给服务器时使用公钥进行加密,服务器接收到加密数据之后使用私钥进行解密。 
1. 创建密钥对KeyPair: 
Java代码

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

下面给出工具类

package com.excelsoft.common.crypto;  import java.io.IOException;  import java.security.Key;  import java.security.KeyPair;  import java.security.KeyPairGenerator;  import java.security.MessageDigest;  import java.security.NoSuchAlgorithmException;  import java.security.PrivateKey;  import java.security.PublicKey;  import java.security.SecureRandom;  import java.security.Signature;  import javax.crypto.Cipher;  import javax.crypto.SecretKey;  import javax.crypto.SecretKeyFactory;  import javax.crypto.spec.DESKeySpec;  import org.apache.commons.logging.Log;  import org.apache.commons.logging.LogFactory;  import sun.misc.BASE64Decoder;  import sun.misc.BASE64Encoder;  /**  * 功能简述: 加密解密工具类,对MD5/BASE64/DES/RSA等算法提供了包装.  * @author Nick Xu  * @version 1.0  */  public class EncryptUtil {      private static Log logger = LogFactory.getLog(EncryptUtil.class);      private static final int KEY_SIZE = 1024;      private static final String  MD5_ALGORITHM= "md5";      private static final String  DES_ALGORITHM= "des";      private static final String  RSA_ALGORITHM= "rsa";      private static final String  SIGNATURE_ALGORITHM= "MD5withRSA";      private static MessageDigest md5;      private static BASE64Encoder encoder;      private static BASE64Decoder decoder;      private static SecureRandom random;      private static KeyPair keyPair;      private EncryptUtil() {      }      static {          try {              md5 = MessageDigest.getInstance(MD5_ALGORITHM);              KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM);              keyPairGenerator.initialize(KEY_SIZE);              keyPair = keyPairGenerator.generateKeyPair();          }          catch (NoSuchAlgorithmException e) {              // Exception handler              logger.error(e);          }          encoder = new BASE64Encoder();          decoder = new BASE64Decoder();          random = new SecureRandom();      }      /**      * 功能简述: 使用md5进行单向加密.      */      public static String encryptMD5(String plainText) {          byte[] cipherData = md5.digest(plainText.getBytes());          StringBuilder builder = new StringBuilder();          for(byte cipher : cipherData) {              String toHexStr = Integer.toHexString(cipher & 0xff);              builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr);          }          return builder.toString();      }      /**      * 功能简述: 使用BASE64进行加密.      * @param plainData 明文数据      * @return 加密之后的文本内容      */      public static String encryptBASE64(byte[] plainData) {          return encoder.encode(plainData);      }      /**      * 功能简述: 使用BASE64进行解密.      * @param cipherText 密文文本      * @return 解密之后的数据      */      public static byte[] decryptBASE64(String cipherText) {          byte[] plainData = null;          try {              plainData =  decoder.decodeBuffer(cipherText);          }          catch (IOException e) {              // Exception handler              logger.error(e);          }          return plainData;      }      /**      * 功能简述: 使用DES算法进行加密.      * @param plainData 明文数据      * @param key   加密密钥      * @return        */      public static byte[] encryptDES(byte[] plainData, String key) {          return processCipher(plainData, createSecretKey(key), Cipher.ENCRYPT_MODE, DES_ALGORITHM);      }      /**      * 功能简述: 使用DES算法进行解密.      * @param cipherData    密文数据      * @param key   解密密钥      * @return      */      public static byte[] decryptDES(byte[] cipherData, String key) {          return processCipher(cipherData, createSecretKey(key), Cipher.DECRYPT_MODE, DES_ALGORITHM);      }      /**      * 功能简述: 根据key创建密钥SecretKey.      * @param key       * @return      */      private static SecretKey createSecretKey(String key) {          SecretKey secretKey = null;          try {              DESKeySpec keySpec = new DESKeySpec(key.getBytes());              SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);              secretKey = keyFactory.generateSecret(keySpec);          }          catch (Exception e) {              // Exception handler              logger.error(e);          }          return secretKey;      }      /**      * 功能简述: 加密/解密处理流程.      * @param processData   待处理的数据      * @param key   提供的密钥      * @param opsMode   工作模式      * @param algorithm   使用的算法      * @return        */      private static byte[] processCipher(byte[] processData, Key key, int opsMode, String algorithm) {          try{               Cipher cipher = Cipher.getInstance(algorithm);              cipher.init(opsMode, key, random);              return cipher.doFinal(processData);          }          catch (Exception e) {              // Exception handler              logger.error(e);          }          return null;      }      /**      * 功能简述: 创建私钥,用于RSA非对称加密.      * @return      */      public static PrivateKey createPrivateKey() {          return keyPair.getPrivate();      }      /**      * 功能简述: 创建公钥,用于RSA非对称加密.      * @return      */      public static PublicKey createPublicKey() {          return keyPair.getPublic();      }      /**      * 功能简述: 使用RSA算法加密.      * @param plainData 明文数据      * @param key   密钥      * @return      */      public static byte[] encryptRSA(byte[] plainData, Key key) {          return processCipher(plainData, key, Cipher.ENCRYPT_MODE, RSA_ALGORITHM);      }      /**      * 功能简述: 使用RSA算法解密.      * @param cipherData    密文数据      * @param key   密钥      * @return      */      public static byte[] decryptRSA(byte[] cipherData, Key key) {          return processCipher(cipherData, key, Cipher.DECRYPT_MODE, RSA_ALGORITHM);      }      /**      * 功能简述: 使用私钥对加密数据创建数字签名.      * @param cipherData     已经加密过的数据      * @param privateKey    私钥      * @return      */      public static byte[] createSignature(byte[] cipherData, PrivateKey privateKey) {          try {              Signature signature  = Signature.getInstance(SIGNATURE_ALGORITHM);              signature.initSign(privateKey);              signature.update(cipherData);              return signature.sign();          }          catch (Exception e) {              // Exception handler              logger.error(e);           }          return null;      }      /**      * 功能简述: 使用公钥对数字签名进行验证.      * @param signData  数字签名      * @param publicKey 公钥      * @return      */      public static boolean verifySignature(byte[] cipherData, byte[] signData, PublicKey publicKey) {          try {              Signature signature  = Signature.getInstance(SIGNATURE_ALGORITHM);              signature.initVerify(publicKey);              signature.update(cipherData);              return signature.verify(signData);          }          catch (Exception e) {              // Exception handler              logger.error(e);          }          return false;      }  }  
原创粉丝点击