按:以下文字涉及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;
    }
}

您可以从http://www.box.net/shared/cyg98xgz78 获得上述代码涉及到的两个实例工程。

好了,感谢您看到这里,希望此文字没有耽误您太多宝贵时间。

使用RSA进行信息加密解密的WebService示例的更多相关文章

  1. python RSA加密、解密、签名

    python RSA加密.解密.签名 python中用于RSA加解密的库有好久个,本文主要讲解rsa.M2Crypto.Crypto这三个库对于RSA加密.解密.签名.验签的知识点. 知识基础 加密是 ...

  2. 通过ios实现RSA加密和解密

    在加密和解密中,我们需要了解的知识有什么事openssl:RSA加密算法的基本原理:如何通过openssl生成最后我们需要的der和p12文件. 废话不多说,直接写步骤: 第一步:openssl来生成 ...

  3. C#实现RSA加密和解密详解

    原文:C#实现RSA加密和解密详解 RSA加密解密源码: Code highlighting produced by Actipro CodeHighlighter (freeware) http:/ ...

  4. ASP.NET Core RSA加密或解密

    前言 这两天主要是公司同事用到了RSA加密,事后也看了下,以为很简单,最终利用RSACryptoServiceProvider来实现RSA加密,然后大致了解到RSACryptoServiceProvi ...

  5. C#实现RSA加密与解密、签名与认证(转)

    一.RSA简介 RSA公钥加密算法是1977年由Ron Rivest.Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的.RSA取名来自开发他们三者的名字.RSA是目前最有影响力 ...

  6. RSA公钥文件解密密文的原理分析

    前言 最近在学习RSA加解密过程中遇到一个这样的难题:假设已知publickey公钥文件和加密后的密文flag,如何对其密文进行解密,转换成明文~~ 分析 对于rsa算法的公钥与私钥的产生,我们可以了 ...

  7. RSA加密和解密工具类

    import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import java.security.*; i ...

  8. IOS, Android, Java Web Rest : RSA 加密和解密问题

    IOS, Android, Java Web Rest :  RSA 加密和解密问题 一对公钥私钥可以使用 OpenSSL创建, 通常 1024位长度够了. 注意: 1. 公钥私钥是BASE64编码的 ...

  9. C#实现RSA加密与解密、签名与认证

    一.RSA简介 RSA公钥加密算法是1977年由Ron Rivest.Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的.RSA取名来自开发他们三者的名字.RSA是目前最有影响力 ...

随机推荐

  1. PHP 使用协同程序实现合作多任务

    多任务协作 如果阅读了上面的logger()例子,那么你认为“为了双向通信我为什么要使用协程呢? 为什么我不能只用常见的类呢?”,你这么问完全正确.上面的例子演示了基本用法,然而上下文中没有真正的展示 ...

  2. visual studio 2017 报错 无法下载安装文件。请检查Internet连接,然后重试

    vs下载完离线安装包在无网络环境下点击安装时出现无法下载安装文件.请检查Internet连接,然后重试 原因是证书没有导 解决方法 打开刚刚存放离线文件的路径,比如D:\vs2017offline,然 ...

  3. C#--反射技术

    反射:反射为了动态(比如动态的加载dll,动态创建类型.动态调用方法等) 引用 using System.Reflection 原理: 一个类库编译后会生成一个以.dll结尾的文件,一个以.pdb结尾 ...

  4. javascript中 try catch用法

    javascript中 try catch用法 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2015-08-16我要评论 JS try catch语句一般在什么情况下使用?是必须使 ...

  5. ubuntu 安装MySQLdb

    ubuntu运行sudo pip install MySQL-python安装MySQLdb时报错:Command "python setup.py egg_info" faile ...

  6. X86汇编概要

    来自:https://www.cnblogs.com/jiftle/p/8453106.html 本文翻译自:http://www.cs.virginia.edu/~evans/cs216/guide ...

  7. 正则表达式(Swift)

    课题 使用正则表达式匹配字符串 使用正则表达式 "\d{3}-(\d{4})-\d{2}" 匹配字符串 "123-4567-89" 返回匹配结果:'" ...

  8. 批量压缩文件.net

    C#调用 ICSharpCode.SharpZipLib.Zip 实现解压缩功能公用类 最近想用个解压缩功能 从网上找了找 加自己修改,个人感觉还是比较好用的,直接上代码如下 using System ...

  9. 页面中 json 格式显示 数据

    在页面中,有时候我们需要的不仅仅是将数据显示出来,而且要以以 json 的格式显示数据,如显示接口的时候 我们需要如下显示 这个时候,主要用到了 <pre> 标签 $.get(" ...

  10. Python中文件编码的检测

    前言: 文件打开的原则是“ 以什么编码格式保存的,就以什么编码格式打开 ”,我们常见的文件一般是以“ utf-8 ”或“ GBK ”编码进行保存的,由于编辑器一般设置了默认的保存和打开方式,所以我们在 ...