http://www.blogjava.net/heyang/archive/2010/12/02/

http://www.blogjava.net/heyang/archive/2010/12/02/339589.html

使用RSA进行信息加密解密的WebService示例 按:以下文字涉及RSA对WebService传递的数据的加密解密,如果您已经熟知RSA或是有其它更好的方法请不要往下看以免浪费时间.

WebService采用的协议是SOAP,它基于HTTP,而HTTP是明文方式,也就是说,采用WebService传递的数据是明文的。如果是天气预报这种公开的只读信息的WebService无所谓,如果涉及写入或是和私密数据相关,那么明文传递就有很大的潜在危险性,必须加以遏止。

一般来说有两种方法,一是采用https加密的方式,另一种是用非对称加密算法对数据加密,下文提到的RSA就是第二种。

使用RSA对WebService传递的信息加密解密的基本思想是:服务器端提供一个WebService方法byte[] getServerPublicKey(),客户端可以以此得到服务器端的公钥,然后使用服务器端的公钥对要传出去的数据进行RSA加密,并附带以自己的公钥;服务器端得到客户端的请求后,先用自己的私钥解密客户端送来的数据,得到处理结果后用客户端提供的公钥加密,然后传回;客户端得到服务器端的返回数据后,用自己的私钥进行解密,最终得到了服务器端的真实数据。服务器端和客户端各自保存自己的RSA私钥用于解密,提供给对方RSA公钥进行加密,这样中间传递的信息就安全了。

加密解密示意顺序图:

下面是服务器端实现类的代码: package com.heyang;

public class ServiceImpl implements IService{ @Override public byte[] getResonse(byte[] params, byte[] clientPublicKey) { try { // 使用自己的私钥解密客户端用服务器端公钥加密的数据 String decryptString=SecurityUtil.getCoder().getDecryptString(params);

        // 要返回的结果
        String response="你好!"+decryptString;
        
        // 使用客户端提供的公钥对返回的数据进行加密
        byte[] retval=SecurityUtil.getCoder().getEncryptArray(response, clientPublicKey);
        
        return retval;
    } catch (Exception e) {
        e.printStackTrace();
        
        return null;
    }
}

@Override
public byte[] getServerPublicKey() {
    return SecurityUtil.getCoder().getPublicKey();
}

}

客户端调用服务器端的代码: package com.heyang;

import org.codehaus.xfire.XFireFactory; import org.codehaus.xfire.client.XFireProxyFactory; import org.codehaus.xfire.service.Service; import org.codehaus.xfire.service.binding.ObjectServiceFactory;

public class Test { public static void main(String[] args) { Service srvcModel = new ObjectServiceFactory().create(IService.class); XFireProxyFactory factory = new XFireProxyFactory(XFireFactory .newInstance().getXFire());

    String helloWorldURL = "http://localhost:8080/XfireSample/services/hello";
    try {
        IService srvc = (IService) factory.create(srvcModel, helloWorldURL);

        // 得到服务器端的公钥
        byte[] serverPublicKey=srvc.getServerPublicKey();
        System.out.print("从服务器端得到的公钥为:");
        for(byte b:serverPublicKey){
            System.out.print(b);
        }
        System.out.println();
        
        
        RSASecurityCoder coder=SecurityUtil.getCoder();
        String requestString="世界";
        
        // 使用服务器端的公钥对要传出去的数据进行加密
        byte[] params=coder.getEncryptArray(requestString, serverPublicKey);
        
        // 得到服务器端的返回结果
        byte[] responseArray=srvc.getResonse(params, coder.getPublicKey());
        
        // 使用自己的私钥进行解密
        String responseString=coder.getDecryptString(responseArray);
        System.out.println("从服务器端返回的字符串结果是:"+responseString);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

输出的结果为: 从服务器端得到的公钥为:48-127-9748136942-12272-122-913111503-127-115048-127-1192-127-1270-575108-121578675121-687-32-1165359-2586-50-127114-24-6769-17-128115114982868-11550-121-111-69-494021-48-22-5844-37-8645-115-125-984651-344761-117-7875-34115-101-119164666123-4211-13-103-62-30-587926842-12338-32-91-24-75-1177128103-12-71108-121-122112-712-1089753-2691-7863-6385-41-10210782-8784120344-69-90474108-3661-47089-1261812510046-123-3910723101 从服务器端返回的字符串结果是:你好!世界

服务器端和客户端使用的RSA加密解密类代码: package com.heyang;

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);
    

    } }

用于初始化RSASecurityCoder实例的SecurityUtil类代码: package com.heyang;

/**

  • 信息安全实用类

  • 说明:

  • 作者:何杨(heyang78@gmail.com)

  • 创建时间:2010-12-2 上午10:57:49

  • 修改时间:2010-12-2 上午10:57:49 */ public class SecurityUtil{ // 用于加密解密的RSA编码类 private static RSASecurityCoder coder;

    /**

    • 初始化coder的静态构造子 */ static{ try { coder=new RSASecurityCoder(); } catch (Exception e) { e.printStackTrace(); } }

    public static RSASecurityCoder getCoder() { return coder; } }

转载于:https://my.oschina.net/u/257088/blog/417398

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值