1. 程式人生 > >使用RSA進行資訊加密解密的WebService示例

使用RSA進行資訊加密解密的WebService示例

按:以下文字涉及RSA對WebService傳遞的資料的加密解密,如果您已經熟知RSA或是有其它更好的方法請不要往下看以免浪費時間.

WebService採用的協議是SOAP,它基於HTTP,而HTTP是明文方式,也就是說,採用WebService傳遞的資料是明文的。如果是天氣預報這種公開的只讀資訊的WebService無所謂,如果涉及寫入或是和私密資料相關,那麼明文傳遞就有很大的潛在危險性,必須加以遏止。

一般來說有兩種方法,一是採用https加密的方式,另一種是用非對稱加密演算法對資料加密,下文提到的RSA就是第二種。

使用RSA對WebService傳遞的資訊加密解密的基本思想是:伺服器端提供一個WebService方法byte[] getServerPublicKey(),客戶端可以以此得到伺服器端的公鑰,然後使用伺服器端的公鑰對要傳出去的資料進行RSA加密,並附帶以自己的公鑰;伺服器端得到客戶端的請求後,先用自己的私鑰解密客戶端送來的資料,得到處理結果後用客戶端提供的公鑰加密,然後傳回;客戶端得到伺服器端的返回資料後,用自己的私鑰進行解密,最終得到了伺服器端的真實資料。伺服器端和客戶端各自儲存自己的RSA私鑰用於解密,提供給對方RSA公鑰進行加密,這樣中間傳遞的資訊就安全了。

加密解密示意順序圖:


下面是伺服器端實現類的程式碼:
package com.heyang;


publicclass ServiceImpl implements IService{
    @Override
    
publicbyte[] 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();
            
            
returnnull;
        }
    }

    @Override
    
publicbyte[] 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;

publicclass Test {
    
publicstaticvoid 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加密解密類
 * 說明:
 * 作者:何楊([email protected])
 * 建立時間:2010-12-1 下午06:14:38
 * 修改時間:2010-12-1 下午06:14:38
 
*/publicclass RSASecurityCoder{
    
// 非對稱加密金鑰演算法privatestaticfinal String Algorithm="RSA";
    
    
// 金鑰長度,用來初始化privatestaticfinalint Key_Size=1024;
    
    
// 公鑰privatefinalbyte[] publicKey;
    
    
// 私鑰privatefinalbyte[] 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
     
*/publicbyte[] 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);
        
        
// 得到解密後的字串returnnew String(arr);
    }

    
publicbyte[] getPublicKey() {
        
return publicKey;
    }
    
    
publicstaticvoid 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;

/**
 * 資訊保安實用類
 * 說明:
 * 作者:何楊([email protected])
 * 建立時間:2010-12-2 上午10:57:49
 * 修改時間:2010-12-2 上午10:57:49
 
*/publicclass SecurityUtil{
    
// 用於加密解密的RSA編碼類privatestatic RSASecurityCoder coder;
    
    
/**
     * 初始化coder的靜態構造子
     
*/static{
        
try {
            coder
=new RSASecurityCoder();
        } 
catch (Exception e) {
            e.printStackTrace();
        }
    }

    
publicstatic RSASecurityCoder getCoder() {
        
return coder;
    }
}


您可以從http://www.box.net/shared/cyg98xgz78 獲得上述程式碼涉及到的兩個例項工程。

好了,感謝您看到這裡,希望此文字沒有耽誤您太多寶貴時間。

相關推薦

使用RSA進行資訊加密解密WebService示例

按:以下文字涉及RSA對WebService傳遞的資料的加密解密,如果您已經熟知RSA或是有其它更好的方法請不要往下看以免浪費時間. WebService採用的協議是SOAP,它基於HTTP,而HTTP是明文方式,也就是說,採用WebService傳遞的資料是明文的。如果是天氣預報這種公開的只讀資訊的Web

使用crypto.js進行資訊加密解密

<script type="text/javascript" src="./crypto-js.js"></script> <script type="text/javascript"> var password = 'password' // 待加密欄位

python進行des加密解密,而且可以與JAVA進行互相加密解密

odi times pla dea details names ideal cati encrypt import binasciifrom pyDes import des, CBC, PAD_PKCS5import uuidimport time# pip instal

java之--簡單RSA算法加密解密

bytes 信任 文件中 實現 public args 路徑 int 指定 //加密協議 public class rsa_asc { /** 指定加密算法為DESede */ private static String ALGORITHM = "RSA";

安全不安全002:C#實現RSA算法加密解密

RSA C#通過前面的文章我們學會了如何生成公鑰和私鑰,詳見這篇文章:https://blog.csdn.net/yysyangyangyangshan/article/details/80368397。那麽,我們來看在C#中如何實現RSA加密解密。直接上代碼,如下類是RSA算法實現的加密,加解密,簽名以及簽

php openssl_sign() 語法+RSA公私鑰加密解密,非對稱加密演算法詳解

其實有時候覺得寫部落格好煩,就個函式就開篇部落格。很小的意見事情而已,知道的人看來多取一舉,或者說沒什麼必要,浪費時間,不知道的人就會很鬱悶。技術就是這樣的,懂的人覺得真的很簡單啊,不知道的人真的好難。。。 一般在跟第三方介面對接資料的時候,為了保證很多都使用的RSA簽名,沒性趣瞭解的同學只需要

openssl RSA非對稱加密解密

需要先了解的openssl系列函式 openssl_pkey_get_private 從證書中解析獲取私鑰,以供使用。成功,返回真實的金鑰資源識別符號(Resource ID),否則返回false openssl_pkey_get_public 從證書中解析獲取公鑰,以供使用。成功,返

RSA私鑰加密解密

Copyright © 2018 Joyce_BY All rights reserved. Contact by [email protected] 實驗原理及演算法 generate key 本次模擬利用私鑰(n,sID)生成公鑰,具體過程如下: A)選擇

.NET中進行Base64加密解密

/// <summary>   /// Base64加密   /// </summary>   /// <param name="Message"></param>   /// <returns></returns>   public s

使用Python進行AES加密解密功能實現

PyCrypto是一款非常實用的Python加密模組,最近寫了一個檔案加密指令碼需要用到AES加密,和大家分析一下心得。 下載與安裝:PyCrypto專案已經於2015年7月停止了,下面是官方的下載地址。 https://www.dlitz.net/software/pycrypto/ 如果是l

php實現openssl RSA非對稱加密解密

今天跟第三方公司對接別人看了我寫的文件當時文件寫的是DES加密,然後我的一個回答都讓我覺得對不起別人,我說了是AES加密,當時AES和RSA加解密的原理我不瞭解導致我也誤解了別人,今天就特意去理解了一下,下面就看一下RSA非對稱的加解密吧 首先先來說一下RSA和AES的區別

使用C++對資料進行Base64加密解密

首先是對資料的base64加密 std::string encode_base64(const std::string& d, bool base64url = false) { const char alphabet_base64[] = "ABCDEFGH" "IJKLM

java實現RSA的簡單加密解密

RSAUtil package com.zhuyun.rsa; import java.io.IOException; import java.security.KeyFactory; import java.security.KeyPair; import java

windows中使用Python進行AES加密解密-加密解密功能實現

PyCrypto是一款非常實用的Python加密模組,最近寫了一個檔案加密指令碼需要用到AES加密(http://blog.csdn.net/u013578500/article/details/77916990),和大家分析一下心得。 下載與安裝:PyCrypto專案

PHP正確進行AES加密解密的方法

廢話不多說,直接上程式碼 <?php namespace Aes; class Aes { /** * var string $method 加解密方法,可通過openssl_get_cipher_methods()獲得 */

今天給大家介紹一下SpringBoot框架中URL引數如何進行Base64加密解密

/** * * Base64 encode / decode * * @author haitao.tu * @date 2010-04-26 * @email [email protected] * */ function Base64() { // private proper

如何利用異或運算進行簡單加密解密

利用“^”異或運算對字串進行加密 思路:1.先建立字串輸入的Scanner; 2.通過char[] array = password.toCharArray();// 獲取字元陣列; 3.遍歷字元陣列,按目前理解要用到遍歷:陣列所有元素進行訪問,比如你要輸出數組裡所有

windows中使用Python進行AES加密解密-文字檔案加密工具

之前的文章http://blog.csdn.net/u013578500/article/details/77905924 簡單介紹了一下使用PyCrypto模組實現對字串的加密解密,裡面有提到我利用這個模組寫了一個對文字檔案進行加密解密的小指令碼,這裡和大家分享一下。 1

golang實現md5、RSA、base64 加密解密

package tools import ( "crypto/md5" "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/base64"

利用RSACryptoServiceProvider進行RSA加密解密

rop color ria keyvalue ngs eat splay null crypto 利用RSACryptoServiceProvider進行RSA加密解密 加密獲取公私鑰 static void Main(string[] args)