当柳上原的风吹向天际的时候...

真正的快乐来源于创造

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks
按:以下文字涉及RSA解密加密的基本操作,您如果已经知晓就不用浪费时间了。

在加密解密过程中,如果加密解密双方都使用同一密钥,那么泄密的可能性还是存在的,无论你把这个密钥放在代码,文件或是数据库中。最好是密钥分成两部分,公钥提供出去给应答者,让它给返回的结果加密,请求者得到返回结果后,用自己的私钥将其解密,公钥和私钥都由程序生成。这样,客户端和服务器端程序的所有者和编写者都难以知道每个客户端的私钥是什么,从而难以破解数据。RSA就是实现这一想法的途径之一。

举例来说,现在有一客户端视图和WebService服务器端通信,假如服务器端的响应函数是 String getResponse(String params,byte[] publicKeyArray);两边程序都有下面的RSASecurityCoder类,客户端在发送请求前,可以得到此类的一个实例,并得到其公钥,然后调用服务器端的getResponse函数,公钥就是这个函数的第二个参数;服务器端得到请求后,处理得到结果,然后用第二个参数--客户端送来的公钥进行加密,然后送回结果;客户端得到结果后用自己的私钥进行解密就可以了。这样,信息在传输过程的安全性就有了充分的保证了。

下面请看代码:
package com.heyang.util;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

/**
 * RSA加密解密类
 * 说明:
 * 作者:何杨(heyang78@gmail.com)
 * 创建时间:2010-12-1 下午06:14:38
 * 修改时间:2010-12-1 下午06:14:38
 
*/
public class RSASecurityCoder{
    
// 非对称加密密钥算法
    private static final String Algorithm="RSA";
    
    
// 密钥长度,用来初始化
    private static final int Key_Size=1024;
    
    
// 公钥
    private final byte[] publicKey;
    
    
// 私钥
    private final byte[] privateKey;
    
    
/**
     * 构造函数,在其中生成公钥和私钥
     * 
@throws Exception
     
*/
    
public RSASecurityCoder() throws Exception{
        
// 得到密钥对生成器
        KeyPairGenerator kpg=KeyPairGenerator.getInstance(Algorithm);
        kpg.initialize(Key_Size);
        
        
// 得到密钥对
        KeyPair kp=kpg.generateKeyPair();
        
        
// 得到公钥
        RSAPublicKey keyPublic=(RSAPublicKey)kp.getPublic();
        publicKey
=keyPublic.getEncoded();
        
        
// 得到私钥
        RSAPrivateKey keyPrivate=(RSAPrivateKey)kp.getPrivate();
        privateKey
=keyPrivate.getEncoded();
    }
    
    
/**
     * 用公钥对字符串进行加密
     * 
     * 说明:
     * 
@param originalString
     * 
@param publicKeyArray
     * 
@return
     * 
@throws Exception
     * 创建时间:2010-12-1 下午06:29:51
     
*/
    
public byte[] getEncryptArray(String originalString,byte[] publicKeyArray) throws Exception{
        
// 得到公钥
        X509EncodedKeySpec keySpec=new X509EncodedKeySpec(publicKeyArray);
        KeyFactory kf
=KeyFactory.getInstance(Algorithm);
        PublicKey keyPublic
=kf.generatePublic(keySpec);
        
        
// 加密数据
        Cipher cp=Cipher.getInstance(Algorithm);
        cp.init(Cipher.ENCRYPT_MODE, keyPublic);
        
return cp.doFinal(originalString.getBytes());
    }
    
    
    
/**
     * 使用私钥进行解密
     * 
     * 说明:
     * 
@param encryptedDataArray
     * 
@return
     * 
@throws Exception
     * 创建时间:2010-12-1 下午06:35:28
     
*/
    
public String getDecryptString(byte[] encryptedDataArray) throws Exception{
        
// 得到私钥
        PKCS8EncodedKeySpec keySpec=new PKCS8EncodedKeySpec(privateKey);
        KeyFactory kf
=KeyFactory.getInstance(Algorithm);
        PrivateKey keyPrivate
=kf.generatePrivate(keySpec);
        
        
// 解密数据
        Cipher cp=Cipher.getInstance(Algorithm);
        cp.init(Cipher.DECRYPT_MODE, keyPrivate);
        
byte[] arr=cp.doFinal(encryptedDataArray);
        
        
// 得到解密后的字符串
        return new String(arr);
    }

    
public byte[] getPublicKey() {
        
return publicKey;
    }
    
    
public static void main(String[] arr) throws Exception{
        String str
="你好,世界! Hello,world!";
        System.out.println(
"准备用公钥加密的字符串为:"+str);
        
        
// 用公钥加密
        RSASecurityCoder rsaCoder=new RSASecurityCoder();
        
byte[] publicKey=rsaCoder.getPublicKey();        
        
byte[] encryptArray=rsaCoder.getEncryptArray(str, publicKey);
        
        System.out.print(
"用公钥加密后的结果为:");
        
for(byte b:encryptArray){
            System.out.print(b);
        }
        System.out.println();
        
        
// 用私钥解密
        String str1=rsaCoder.getDecryptString(encryptArray);
        System.out.println(
"用私钥解密后的字符串为:"+str1);
    }
}

输出:
准备用公钥加密的字符串为:你好,世界! Hello,world!
用公钥加密后的结果为:
62-90-128-107-100-7070-11157-123-9160-6-116-68-1476-45-112-107-53-90107-84-670-9862-35-11116-83-10864312117-96-117-56995-2510321-89-89-828977-8810940100-91-76986562-222574-12815-120118-103-11-121-6030-6490-79-804911111-17-473984-7046-12294-8454-27108-26-11281-43833782-7926-612284-81781132357-3108-12673245-5111912-86-10041-799104-8146-5712374-55
用私钥解密后的字符串为:你好,世界! Hello,world
!


看到这里,如果有人说客户端调用服务器端的getResponse函数时,第一个参数params不是还会暴露一部分信息吗? 不要怕,我们可以让服务器端再准备一个WebService函数 byte[] getServerPublicKey();客户端可以调用这个函数以得到服务器端的公钥,然后把params用这个公钥加密,然后再调用getResponse(String params,byte[] publicKeyArray)函数,服务器端接到请求后,用自己的私钥对第一个参数进行解密就可以了。这样,所有信息都得到了保护。

如果String的表现力不够怎么办,有了XML的帮助,这从来不是问题,您说呢?

好了,感谢您看到这里,希望上面的文字能对您有所帮助;如果您要使用的话,上面的代码需要改写一下,相信您知道该怎么办。

posted on 2010-12-01 19:19 何杨 阅读(490) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: