通过代码示例学习Java安全技术(第6部分:加密和解密技术实现)

前言

随着网络应用的不断深入,特别是电子商务应用的普及,对网络应用的安全提出了许多新的和更高的要求。在Java及J2EE应用系统平台环境中,提供了多层次和多种形式的安全技术的支持,如JCE(Java密码扩展)、JSSE(Java安全套接字扩展)和JAAS(Java 认证和授权服务)等。从而可以在一定的程度上保证应用系统的安全性。比如,将Web应用中的客户端和Web服务器端之间的通讯连接方式从Http方式改变为Https方式,则是对Web应用在协议层次的安全保护技术——Https是在协议层对Http的再次封装,加入了SSL/TLS等相关的技术。

作者根据自身多年的软件开发实践和经验总结,结合多年的IT职业培训的教学和高校软件学院一线的教学工作体验,在本系列文档中通过具体的程序代码示例为读者介绍Java 及J2EE应用系统平台环境中的安全相关的应用技术。主要的目的是希望能够将作者在项目开发中所涉及的安全应用技术进行总结和提炼,以成功的经验或者失败的教训为读者减少软件开发中由于安全技术的欠缺而导致应用系统在使用中所带来的各种风险,同时也为高校师生总结出Java及J2EE应用系统平台环境中的相关安全技术,增强和培养软件专业的学生对应用系统安全技术的关注度和提高对相关技术的应用能力。

消息摘要可以确保消息(或者信息)的完整性,但不能用来确保消息(或者信息)的机密性。要确保机密性,开发人员需要对通讯过程中的各种消息(或者信息)进行加密转换,然后在接收端再进行解密转换以获得原始的信息。之所以在网络通讯中需要对信息进行加密转换,主要是因为通信的双方使用的是公开的信道,而信道上是可能有窃听者的。如果直接使用明文传输和接收消息(或者信息)——也就是不进行加密转换为不可直接理解的密文,那么窃听者就可以知道通讯过程中消息(或者信息)的具体内容。

目前的加密算法主要可以分为如下的三类算法:对称加密、不对称加密和不可逆加密。本文档主要涉及如何保持通讯过程信息的机密性、Java对加密和解密技术的支持和RSA不对称加密解密技术及原理、RSA不对称加密解密技术实现示例,对称加密解密技术及应用示例——包括DES加密和解密技术实现示例、DESede加密和解密技术实现示例和AES加密和解密技术实现示例等方面的实现示例和详细的程序代码。

杨教授大学堂精心创作有系列化的优秀程序员职业提升必读技术资料,这些资料将系统地从软件设计和开发实现的“设计思想”、“管理策略”、“技术实现”和“经验方法”等方面与读者进行充分的交流,涉及作者对软件开发设计思想和原则、课程设计、项目实训、软件实现技术等方面的学习心得体会和应用技巧、经验总结。

本文目录

1.1保持通讯过程信息的机密性 (3)

1.1.1Java对加密和解密技术的支持 (3)

1.1.2Java对Base64编码转换的技术支持 (5)

1.1.3Java对MD5不可逆加密转换的技术支持 (6)

1.1.4Java对数字签名的技术支持 (7)

1.2RSA不对称加密解密技术及应用 (10)

1.2.1RSA不对称加密解密技术及原理 (10)

1.2.2RSA原理型的实现示例 (12)

1.2.3RSA不对称加密解密技术应用示例 (16)

1.3对称加密解密技术及应用示例 (27)

1.3.1DES加密和解密技术实现示例 (27)

1.3.2DESede加密和解密技术实现示例 (42)

1.3.3AES加密和解密技术实现示例 (43)

1.1保持通讯过程信息的机密性

1.1.1Java对加密和解密技术的支持

1、加密和解密技术

(1)什么是加密和解密

消息摘要可以确保消息(或者信息)的完整性,但不能用来确保消息(或者信息)的机密性。要确保机密性,开发人员需要对通讯过程中的各种消息(或者信息)进行加密转换,然后在接收端再进行解密转换以获得原始的信息。

因此,把通讯过程中的重要信息(数据)转换为不可理解的乱码(密文)后再发送的过程称为加密;而到达目的地后再用相同或不同的技术手段还原出(解密)原始信息的过程称为解密。

(2)加密技术主要包括两个要素

算法和密钥。

(3)为什么在网络通讯中需要对信息进行加密

因为通信的双方使用的是公开的信道,而信道上是可能有窃听者的。如果直接使用明文传输和接收消息(或者信息)——也就是不进行加密转换为不可直接理解的密文,那么窃听者就可以知道通讯过程中消息(或者信息)的具体内容。

2、公钥和私钥加密和解密技术

由于加密技术的核心要点是所采用的加密算法,算法如果越安全,加密的结果信息也就越可靠。目前的加密算法主要可以分为如下的三类算法。

(1)对称加密

(2)不对称加密

(3)不可逆加密

3、对称加密技术

(1)什么是对称加密技术

在对称加密算法中,数据发送方将原始数据(明文)和所采用的加密密钥一起都经过特殊的加密算法处理后,使其变成加密的密文后再发送出去。接收方的相关人员收到密文后,需要使用加密时的密钥及相同算法的逆算法(解密算法)对所接收到的密文进行解密,才能使其恢复成可读的原始数据(明文)。(2)主要的对称加密技术

DES、3DES和IDEA等都是目前常用的对称加密算法,美国国家标准局倡导的AES即将作为新标准取代早期的DES加密算法。但目前的对称加密技术主要是以数据加密标准(DES,Data Encryption Standard)算法为典型代表,因为对称加密算法的主要优点是算法公开、计算量小、加密速度快、加密效率高。

在对称加密算法中,对同样的信息应用不同的密钥,加密结果和解密结果在理论上都是不相同的。但对称加密算法在实际应用中的不足之处主要是要求通讯中的双方都要使用同样的密钥,这在一定的程度上的安全性可能得不到保证。

4、不对称加密

(1)什么是不对称加密技术

不对称加密算法采用两个完全不同但又是相互匹配的一对密钥——公钥和私钥,而只有使用匹配的一对公钥和私钥,才能完成对原始数据(明文)的加密和对密文进行解密的过程。

(2)主要的不对称加密技术

广泛应用的非对称加密算法有RSA算法和美国国家标准局提出的DSA。

(3)不对称加密技术的主要应用过程

在应用中,信息的发送方采用公钥加密,接收方解密密文时只需要使用自己的私钥完成解密过程;而如果再需要将信息从接收方返回给发送方时,接收方仍然采用自己的私钥完成加密过程并返回给发送方,此时的信息接收者(也就是原始信息的发送方)仍然采用公钥解密出返回的信息明文。

采用不对称加密算法时,通讯过程中的双方在进行信息通讯之前,信息的接收方必须要将自己早已随机生成的公钥发送给信息的发送方,但自己保留对应的私钥以便于能够解密所接收到的密文信息。因此,在不对称加密的应用中,不仅可以用公钥加密,也还可以用私钥加密;但采用公钥加密的结果密文则必须要用对应的私钥解密,而采用私钥加密的结果密文,则也必须要用对应的公钥解密。

在加密和解密过程中,如果公钥和私钥不相互对应,则会出现如下的异常信息:javax.crypto.BadPaddingException:Data must start with zero。如下示图所示:

5、不可逆加密(单向加密)

(1)什么是不可逆加密技术

不可逆加密算法的特征是在加密过程中不需要使用密钥(因为不需要解密过程或者也无法进行解密),输入原始数据(明文)后由加密系统直接经过加密算法的处理并转换为密文,这种加密转换后的

数据是无法被解密的。因此,称为不可逆加密技术。

(2)主要的不可逆加密技术

不可逆加密算法主要有RSA公司发明的MD5算法和由美国国家标准局建议的不可逆加密标准SHS (Secure Hash Standard,安全杂乱信息标准)、SHA(Secure Hash Algorithm,安全散列算法)——其中规定了SHA-1、SHA-224、SHA-256、SHA-384和SHA-512这几种单向散列算法等。

(3)不可逆加密的主要用途

不可逆加密的主要应用是为了校验数据在传输过程中是否被修改,因为加密转换后的结果是与原始的信息保持一一对应的关系,而且加密转换后的结果还是不解密的,从而可以避免伪造加密转换后的结果。

1.1.2Java对Base64编码转换的技术支持

1、Base64是一种基于64个可打印字符表示二进制数据的一种表示法

Base64本质上不属于加密转换,而是一个编码转换和反转换,有利于信息的传输和使用。

2、Base64编码实现的基本原理

Base64常用于在通常处理文本数据的场合,可以表示、传输、存储一些二进制数据,2的6次方等于64,所以每6个位元为一个单元,对应某个可打印字符。三个字节有24个位元,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。

在Base64中的可打印字符包括字母A-Z、a-z(大小写字母各26个)、数字0-9(10个数字),这样共有62个字符,此外两个可打印符号在不同的系统中而不同——加号“+”和斜杠“/”。其实如果再加上作为垫字的“=”,实际上是65个字符。

3、Base64编码的后果将会增加信息的长度

Base64将三个字节转化成四个字节,因此Base64编码后的文本,会比原文本大出三分之一左右。

4、为什么要对信息进行Base64编码转换

(1)所有的二进制文件,都可以采用Base64编码转换为可打印的文本编码,然后可以使用文本软件进行编辑和能够对文本进行加密转换。

(2)Base64编码可用于在HTTP环境下传递较长的标识信息和将二进制数据编码为适合能够在URL(包括隐藏表单域)中的数据形式,由于一些二进制字符在传输协议中属于控制字符,不能直接传送需要进行转换——否则将会与相关的特殊字符产生冲突;同时也还因为采用Base64编码的结果不仅比较简短,同时也具有不可读性——在一定的程度上能够产生出加密的效果。

5、Java中的Base64编码转换的代码示例

下面的orignalMessageByteArray代表需要进行Base64编码转换的原始信息,而encryptResult代表对原始的信息进行Base64编码转换的结果字符串。核心的功能类为sun.misc.BASE64Encoder,但为非官方JDK里面的类。

byte[]orignalMessageByteArray=null;

BASE64Encoder oneBASE64Encoder=new BASE64Encoder();

String encryptResult=oneBASE64Encoder.encodeBuffer(orignalMessageByteArray);

6、Java中的Base64编码反转换的代码示例

byte[]orignalMessageByteArray=null;

String decryptMessageText=null;

BASE64Decoder oneBASE64Decoder=new BASE64Decoder();

try{

orignalMessageByteArray=oneBASE64Decoder.decodeBuffer(decryptMessageText);

}catch(IOException e){

e.printStackTrace();

}

其中的核心的功能类为sun.misc.BASE64Decoder,也为非官方JDK里面的类。

1.1.3Java对MD5不可逆加密转换的技术支持

1、MD5为不可逆加密转换算法

MD5(Message-Digest Algorithm5,信息-摘要算法)是一种用于产生数字签名的单项散列算法,它广泛应用于对信息的加密和文件校验——因为原始信息生成唯一的MD5值。

2、MD5的产生和演变完善

MD5是在1991年由MIT Laboratory for Computer Science(IT计算机科学实验室)和RSA Data Security Inc(RSA数据安全公司)的Ronald L.Rivest教授开发出来,经由MD2、MD3和MD4发展而来。

3、MD5的主要作用

在对大容量信息进行数字签名前被“压缩”成一种保密的格式,也就是将一个任意长度的“字节串”通过一个不可逆的字符串变换算法变换成一个128bit的大整数(用字节表示就是16个字节)。

4、Java中内带有对MD5的技术支持

java.security.MessageDigest类封装MD5的技术支持,下面为实现的代码示例。

byte[]orignalMessageByteArray=null;

/**

*获得MD5摘要算法的MessageDigest对象

*/

java.security.MessageDigest oneMessageDigest=java.security.MessageDigest.getInstance("MD5");

/**

*使用指定的字节更新摘要

*/

oneMessageDigest.update(orignalMessageByteArray);

/**

*获得MD5转换处理后的密文

*/

byte encryptResultByteArray[]=oneMessageDigest.digest();

5、应用BASE64将MD5的128bit大整数再转换

为了有利于MD5加密转换后的128bit大整数在网络上的传输,可以再应用BASE64将MD5的128bit 大整数再转换为字符串,从而可以在网络中传输MD5的处理结果。

1.1.4Java对数字签名的技术支持

1、java.security.Signature类

Signature类用来为应用程序提供数字签名算法功能,而数字签名用于确保数据的验证和完整性。一般包括签名和对签名的结果进行验证两个阶段。

2、实现数字签名的代码片段示例

/**

*下面的someOnePrivateKey代表私钥,而encryptOrignalMessageByteArray代表需要签名的原始信息,而signaturedMessageByteArray代表数字签名后的结果信息

*/

PrivateKey someOnePrivateKey=null;

byte[]encryptOrignalMessageByteArray=null;

byte[]signaturedMessageByteArray=null;

java.security.Signature oneSignature=null;

/**

*采用指定的消息摘要算法创建出数字签名对象实例

*/

try{

oneSignature=java.security.Signature.getInstance("MD5withRSA"); }catch(NoSuchAlgorithmException e){

e.printStackTrace();

}

/**

*用私钥初始化数字签名对象实例

*/

try{

oneSignature.initSign(someOnePrivateKey);

}catch(InvalidKeyException e){

e.printStackTrace();

}

/**

*添加要进行数字签名的信息

*/

try{

oneSignature.update(encryptOrignalMessageByteArray);

}catch(SignatureException e){

e.printStackTrace();

}

/**

*对目标信息进行数字签名,并获得签名后的结果信息

*/

try{

signaturedMessageByteArray=oneSignature.sign();

}catch(SignatureException e){

e.printStackTrace();

}

3、实现校验数字签名的代码片段示例

/**

*下面的someOnePublicKey代表公钥,而encryptResultMessageByteArray代表加密后的结果信息(由信息发送方发送的加密结果信息)——也是需要进行验证的目标信息,而其中的变量signaturedMessageByteArray代表原始的签名信息

*/

PublicKey someOnePublicKey=null;

byte[]encryptResultMessageByteArray=null;

byte[]signaturedMessageByteArray=null;

java.security.Signature oneSignature=null;

/**

*采用指定的消息摘要算法创建出数字签名验证的对象实例

*/

try{

oneSignature=java.security.Signature.getInstance("MD5withRSA");

}catch(NoSuchAlgorithmException e){

e.printStackTrace();

}

/**

*用公钥初始化数字签名验证对象实例

*/

try{

oneSignature.initVerify(someOnePublicKey);

}catch(InvalidKeyException e){

e.printStackTrace();

}

/**

*添加要进行数字签名验证的信息

*/

try{

oneSignature.update(encryptResultMessageByteArray);

}catch(SignatureException e){

e.printStackTrace();

}

/**

*验证数字签名是否有效和正常,返回true代表验证通过

*/

boolean verifyResult=false;

try{

verifyResult=oneSignature.verify(signaturedMessageByteArray);

}catch(SignatureException e){

e.printStackTrace();

}

1.2RSA不对称加密解密技术及应用

1.2.1RSA不对称加密解密技术及原理

1、RSA不对称加密解密技术

RSA不对称加密解密算法是在1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的,RSA是他们三人姓氏开头字母拼在一起组成的。

2、非对称加密解密算法产生的理论基础

1976年,两位美国计算机学家Whitfield Diffie和Martin Hellman,提出了一种崭新构思,可以在不直接传递密钥的情况下,完成对信息的解密过程。

上面的构思被称为“Diffie-Hellman密钥交换算法”——加密和解密可以使用不同的规则,只要这两种规则之间存在某种对应关系即可,从而可以避免对称加密解密算法中需要传递和管理密钥的问题。

3、RSA加密解密算法的安全性

RSA的密钥越长,它也就越难被破解。根据目前已经披露的文献资料,目前被破解的最长RSA密钥是768个二进制位——长度超过768位的密钥,还无法破解。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。

4、RSA的应用流程

(1)信息发送方构建出密钥对(包括有公钥和私钥),并将公钥公布给信息的接收方,但将私钥保留给自己使用。

(2)信息发送方使用私钥加密相关的数据,然后再用私钥对加密后的数据结果进行数字签名,并将数字签名和加密后的数据结果都发送给信息的接收方;信息的接收方则使用公钥解密出数字签名的结果,并验证待解密的数据是否是有效的——没有被修改。如果所接收到的加密结果信息是有效的,则最后将使用公钥对所接收的加密结果数据进行解密。

(3)信息的接收方可以使用公钥加密待返回给信息发送方的处理结果数据,并发送给信息的发送方;信息发送方获得加密的处理结果数据后,可以通过只有自己拥有的私钥解密处理的结果信息。

上述的过程其实也就是通过私钥加密、公钥解密,同时通过私钥签名、公钥验证签名,实现将信息从信息的发送方传输到信息的接收方;而使用公钥加密、私钥解密,则可以完成将信息从信息的接收方返回到信息的发送方的一次数据反馈传递。

5、RSA的主要缺点和应用场合

运算处理的代价很高,尤其是速度较慢,较对称密码算法要慢几个数量级。因此,使用RSA只应该加密少量的数据,而大量数据的加密还要应用对称密码算法实现。

1.2.2RSA原理型的实现示例

1、创建RSA密钥对生成器的代码片段

KeyPairGenerator oneKeyPairGenerator=null;

try{

oneKeyPairGenerator=KeyPairGenerator.getInstance("RSA");

}catch(NoSuchAlgorithmException e){

e.printStackTrace();

}

/**下面的初始化也可以采用SecureRandom提供强加密随机数生成器。本示例使用了默认随机器SecureRandom secrand=new SecureRandom();

*/

oneKeyPairGenerator.initialize(1024);

/**

*下面的代码是产生密钥对,其中的java.security.KeyPair封装密钥对,可以从其中获得公钥和私钥*/

KeyPair someOneKeyPair=oneKeyPairGenerator.generateKeyPair();

注意RSA密钥至少为500位长并且还必须为64的倍数,一般推荐使用1024位;

“oneKeyPairGenerator.initialize(1024);”语句是对RSA密钥进行初始化,设置密钥长度为1024位。

对于密钥对中的公钥和私钥的保存和传输可以使用Java对象流的方式进行保存(序列化)和传送,也可以使用BASE64编码转换后再保存。下面为代码示例:

java.io.ObjectOutputStream out=

new java.io.ObjectOutputStream(new java.io.FileOutputStream("someOnePrivateKey.dat"));

out.writeObject(someOnePrivateKey);

out.close();

out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("someOnePublicKey.dat"));

out.writeObject(someOnePublicKey);

out.close();

2、公钥加密的实现代码示例

javax.crypto.Cipher类为加密和解密提供密码功能

Cipher cipher=null;

try{

cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");

}catch(NoSuchAlgorithmException e){

e.printStackTrace();

}catch(NoSuchPaddingException e){

e.printStackTrace();

}

try{

cipher.init(Cipher.ENCRYPT_MODE,someOneKeyPair.getPublic());

}catch(InvalidKeyException e){

e.printStackTrace();

}

byte[]resultByteArray=null;

try{

resultByteArray=cipher.doFinal(orignalMessage.getBytes("UTF-8"));

}catch(IllegalBlockSizeException e){

e.printStackTrace();

}catch(BadPaddingException e){

e.printStackTrace();

}catch(UnsupportedEncodingException e){

e.printStackTrace();

}

3、私钥加密的实现代码示例

Cipher cipher=null;

try{

cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");

}catch(NoSuchAlgorithmException e){

e.printStackTrace();

}catch(NoSuchPaddingException e){

e.printStackTrace();

}

try{

cipher.init(Cipher.ENCRYPT_MODE,someOneKeyPair.getPrivate());

}catch(InvalidKeyException e){

e.printStackTrace();

}

byte[]resultByteArray=null;

try{

resultByteArray=cipher.doFinal(orignalMessage.getBytes("UTF-8"));

}catch(IllegalBlockSizeException e){

e.printStackTrace();

}catch(BadPaddingException e){

e.printStackTrace();

}catch(UnsupportedEncodingException e){

e.printStackTrace();

}

4、公钥解密的实现代码示例

Cipher cipher=null;

try{

cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");

}catch(NoSuchAlgorithmException e){

e.printStackTrace();

}catch(NoSuchPaddingException e){

e.printStackTrace();

}

try{

cipher.init(Cipher.DECRYPT_MODE,someOneKeyPair.getPublic());

}catch(InvalidKeyException e){

e.printStackTrace();

}

byte[]orignalMessageByteArray=null;

try{

orignalMessageByteArray=cipher.doFinal(resultByteArray);

}catch(IllegalBlockSizeException e){

e.printStackTrace();

}catch(BadPaddingException e){

e.printStackTrace();

}

String orignalMessageStringText=null;

try{

orignalMessageStringText=new String(orignalMessageByteArray,"UTF-8");

}catch(UnsupportedEncodingException e){

e.printStackTrace();

}

5、私钥解密的实现代码示例

Cipher cipher=null;

try{

cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");

}catch(NoSuchAlgorithmException e){

e.printStackTrace();

}catch(NoSuchPaddingException e){

e.printStackTrace();

}

try{

cipher.init(Cipher.DECRYPT_MODE,someOneKeyPair.getPrivate());

}catch(InvalidKeyException e){

e.printStackTrace();

}

byte[]orignalMessageByteArray=null;

try{

orignalMessageByteArray=cipher.doFinal(resultByteArray);

}catch(IllegalBlockSizeException e){

e.printStackTrace();

}catch(BadPaddingException e){

e.printStackTrace();

}

String orignalMessageStringText=null;

try{

orignalMessageStringText=new String(orignalMessageByteArray,"UTF-8");

}catch(UnsupportedEncodingException e){

e.printStackTrace();

}

1.2.3RSA不对称加密解密技术应用示例

1、完整的RSA实现代码示例

package com.px1987.encryptdecrypt;

import java.io.UnsupportedEncodingException;

import java.security.InvalidKeyException;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;

import javax.crypto.Cipher;

import javax.crypto.IllegalBlockSizeException;

import javax.crypto.NoSuchPaddingException;

public class RSAEncryptDecryptDemo{

/**

*publicEncrypt方法实现公钥加密

*@param publicPrivateKeyPair成对的公钥和私钥

*@param orignalMessage原始的明文信息

*@return加密转换后的密文信息

*@throws Exception

*/

public byte[]publicEncrypt(KeyPair publicPrivateKeyPair,String orignalMessage){

/**

*Cipher类封装加密和解密中的密码功能,它是Java Cryptographic Extension(JCE)框架的核心。

*/

Cipher cipher=null;

/**

*为创建Cipher对象,需要调用Cipher类中的getInstance方法并将所请求“转换”的名称传递给它。“转换”始终包括加密算法的名称(例如,DES),后面可能跟有一个反馈模式和填充方案。“转换”可以为以下的形式:

(1)“算法/模式/填充”

(2)“算法”(使用模式和填充方案特定于提供者的默认值)

*/

try{

/**

*下面的语句也可以改变为:cipher=Cipher.getInstance("RSA");

*/

cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");

}catch(NoSuchAlgorithmException e){

e.printStackTrace();

}catch(NoSuchPaddingException e){

e.printStackTrace();

}

try{

/**

*用密钥初始化此Cipher对象(相当于创建该Cipher的一个新实例并将其初始化),其中的第1个参数可以为ENCRYPT_MODE(加密)、DECRYPT_MODE(解密)、WRAP_MODE(密钥包装)或UNWRAP_MODE(密钥解包)

*/

cipher.init(Cipher.ENCRYPT_MODE,publicPrivateKeyPair.getPublic());

}catch(InvalidKeyException e){

e.printStackTrace();

}

byte[]resultByteArray=null;

try{

/**

*对原始的明文信息进行加密,并获得转换后的结果

*/

resultByteArray=cipher.doFinal(orignalMessage.getBytes("UTF-8"));

}catch(IllegalBlockSizeException e){

e.printStackTrace();

}catch(BadPaddingException e){

e.printStackTrace();

}catch(UnsupportedEncodingException e){

e.printStackTrace();

}

return resultByteArray;

}

/**

*publicDecrypt方法实现公钥解密

*@param publicPrivateKeyPair成对的公钥和私钥

*@param resultByteArray待解密的二进制数据

*@return解密转换后的原始明文信息

*@throws Exception

*/

public String publicDecrypt(KeyPair publicPrivateKeyPair,byte[]resultByteArray){

/**

*Cipher类封装加密和解密中的密码功能,它是Java Cryptographic Extension(JCE)框架的核心。

*/

Cipher cipher=null;

/**

*为创建Cipher对象,需要调用Cipher类中的getInstance方法并将所请求“转换”的名称传递给它。“转换”始终包括加密算法的名称(例如,DES),后面可能跟有一个反馈模式和填充方案。“转换”可以为以下的形式:

(1)“算法/模式/填充”

(2)“算法”(使用模式和填充方案特定于提供者的默认值)

*/

try{

/**

*下面的语句也可以改变为:cipher=Cipher.getInstance("RSA");

*/

cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");

}catch(NoSuchAlgorithmException e){

e.printStackTrace();

}catch(NoSuchPaddingException e){

e.printStackTrace();

}

try{

/**

*用密钥初始化此Cipher对象(相当于创建该Cipher的一个新实例并将其初始化),其中的第1个参数可以为ENCRYPT_MODE(加密)、DECRYPT_MODE(解密)、WRAP_MODE(密钥包装)或UNWRAP_MODE(密钥解包)

*/

cipher.init(Cipher.DECRYPT_MODE,publicPrivateKeyPair.getPublic());

}catch(InvalidKeyException e){

e.printStackTrace();

}

byte[]orignalMessageByteArray=null;

try{

/**

*对原始的明文信息进行解密,并获得转换后的解密结果(原始信息)

*/

orignalMessageByteArray=cipher.doFinal(resultByteArray);

}catch(IllegalBlockSizeException e){

e.printStackTrace();

}catch(BadPaddingException e){

e.printStackTrace();

}

String orignalMessageStringText=null;

try{

orignalMessageStringText=new String(orignalMessageByteArray,"UTF-8");

}catch(UnsupportedEncodingException e){

e.printStackTrace();

}

相关文档
最新文档