`

Java加密技术—非对称加密算法RSA

 
阅读更多

RSA 
    这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。 
    这种加密算法的特点主要是密钥的变化,上文我们看到DES只有一个密钥。相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改

流程分析: 

  1. 甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。
  2. 甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。
  3. 乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。按如上步骤给出序列图,如下: 
 
package com.lee.encrypt; 


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

import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

/**
 * RSA安全编码组件
 * 
 * @author lee
 * @version 1.0
 * @since 1.0
 */
public abstract class RSACoder extends Coder {
    public static final String KEY_ALGORITHM = "RSA";
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

    private static final String PUBLIC_KEY = "RSAPublicKey";
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * 用私钥对信息生成数字签名
     * 
     * @param data
     *            加密数据
     * @param privateKey
     *            私钥
     * 
     * @return
     * @throws Exception
     */
    public static String sign(byte[] data, String privateKey) throws Exception {
        // 解密由base64编码的私钥
        byte[] keyBytes = decryptBASE64(privateKey);

        // 构造PKCS8EncodedKeySpec对象
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

        // KEY_ALGORITHM 指定的加密算法
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        // 取私钥匙对象
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);

        // 用私钥对信息生成数字签名
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(priKey);
        signature.update(data);

        return encryptBASE64(signature.sign());
    }

    /**
     * 校验数字签名
     * 
     * @param data
     *            加密数据
     * @param publicKey
     *            公钥
     * @param sign
     *            数字签名
     * 
     * @return 校验成功返回true 失败返回false
     * @throws Exception
     * 
     */
    public static boolean verify(byte[] data, String publicKey, String sign)
            throws Exception {

        // 解密由base64编码的公钥
        byte[] keyBytes = decryptBASE64(publicKey);

        // 构造X509EncodedKeySpec对象
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

        // KEY_ALGORITHM 指定的加密算法
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        // 取公钥匙对象
        PublicKey pubKey = keyFactory.generatePublic(keySpec);

        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(pubKey);
        signature.update(data);

        // 验证签名是否正常
        return signature.verify(decryptBASE64(sign));
    }

    /**
     * 解密<br>
     * 用私钥解密
     * 
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPrivateKey(byte[] data, String key)
            throws Exception {
        // 对密钥解密
        byte[] keyBytes = decryptBASE64(key);

        // 取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

        // 对数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        return cipher.doFinal(data);
    }

    /**
     * 解密<br>
     * 用公钥解密
     * 
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPublicKey(byte[] data, String key)
            throws Exception {
        // 对密钥解密
        byte[] keyBytes = decryptBASE64(key);

        // 取得公钥
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicKey = keyFactory.generatePublic(x509KeySpec);

        // 对数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicKey);

        return cipher.doFinal(data);
    }

    /**
     * 加密<br>
     * 用公钥加密
     * 
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPublicKey(byte[] data, String key)
            throws Exception {
        // 对公钥解密
        byte[] keyBytes = decryptBASE64(key);

        // 取得公钥
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicKey = keyFactory.generatePublic(x509KeySpec);

        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        return cipher.doFinal(data);
    }

    /**
     * 加密<br>
     * 用私钥加密
     * 
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPrivateKey(byte[] data, String key)
            throws Exception {
        // 对密钥解密
        byte[] keyBytes = decryptBASE64(key);

        // 取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);

        return cipher.doFinal(data);
    }

    /**
     * 取得私钥
     * 
     * @param keyMap
     * @return
     * @throws Exception
     */
    public static String getPrivateKey(Map<String, Object> keyMap)
            throws Exception {
        Key key = (Key) keyMap.get(PRIVATE_KEY);

        return encryptBASE64(key.getEncoded());
    }

    /**
     * 取得公钥
     * 
     * @param keyMap
     * @return
     * @throws Exception
     */
    public static String getPublicKey(Map<String, Object> keyMap)
            throws Exception {
        Key key = (Key) keyMap.get(PUBLIC_KEY);

        return encryptBASE64(key.getEncoded());
    }

    /**
     * 初始化密钥
     * 
     * @return
     * @throws Exception
     */
    public static Map<String, Object> initKey() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator
                .getInstance(KEY_ALGORITHM);
        keyPairGen.initialize(1024);

        KeyPair keyPair = keyPairGen.generateKeyPair();

        // 公钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

        // 私钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        Map<String, Object> keyMap = new HashMap<String, Object>(2);

        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }
}
 再给出一个测试类: 
 
package com.lee.encrypt; 



import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

import java.util.Map;

/**
 * 
 * @author lee
 * @version 1.0
 * @since 1.0
 */
public class RSACoderTest {
    private String publicKey;
    private String privateKey;

    @Before
    public void setUp() throws Exception {
        Map<String, Object> keyMap = RSACoder.initKey();

        publicKey = RSACoder.getPublicKey(keyMap);
        privateKey = RSACoder.getPrivateKey(keyMap);
        System.err.println("公钥: \n\r" + publicKey);
        System.err.println("私钥: \n\r" + privateKey);
    }

    @Test
    public void test() throws Exception {
        System.err.println("公钥加密——私钥解密");
        String inputStr = "abc";
        byte[] data = inputStr.getBytes();

        byte[] encodedData = RSACoder.encryptByPublicKey(data, publicKey);

        byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData,
                privateKey);

        String outputStr = new String(decodedData);
        System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);
        assertEquals(inputStr, outputStr);

    }

    @Test
    public void testSign() throws Exception {
        System.err.println("私钥加密——公钥解密");
        String inputStr = "sign";
        byte[] data = inputStr.getBytes();

        byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);

        byte[] decodedData = RSACoder
                .decryptByPublicKey(encodedData, publicKey);

        String outputStr = new String(decodedData);
        System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);
        assertEquals(inputStr, outputStr);

        System.err.println("私钥签名——公钥验证签名");
        // 产生签名
        String sign = RSACoder.sign(encodedData, privateKey);
        System.err.println("签名:\r" + sign);

        // 验证签名
        boolean status = RSACoder.verify(encodedData, publicKey, sign);
        System.err.println("状态:\r" + status);
        assertTrue(status);

    }

}
 控制台输出为:
公钥: 

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGB06cz4zuzfeO7eW9/bQ7wddDQsbf6WABeS5X
WTxIgda62DqK0ceQX6vOW6btbLXtdJV+SocCV9IIqrCm2ZY98LYEQ2dSN8963k5yHFvk0BIyA3Ez
2ZBD0GbSUzgTDWWMuMrdzYKKzirP6zaXVvKTi+p9fNz4D/wwVPQMpOyo7wIDAQAB

私钥: 

MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMYHTpzPjO7N947t5b39tDvB10NC
xt/pYAF5LldZPEiB1rrYOorRx5Bfq85bpu1ste10lX5KhwJX0giqsKbZlj3wtgRDZ1I3z3reTnIc
W+TQEjIDcTPZkEPQZtJTOBMNZYy4yt3NgorOKs/rNpdW8pOL6n183PgP/DBU9Ayk7KjvAgMBAAEC
gYB2GCd2doPaafQnRZILsn/IXznrf6gwIfHCDy1mo+3CY8PVm1uWK7JyU8uWfavXzUvVNwBr1zAa
Ypr71icQ6ZOhgUeQcWBbthVIrb31LosQ1yQ87kjOMPzWE0j8CBQVJzsF33W1pU0/qpa15vjGEg9P
vGOyTEcL1L/9s6+nPbwlYQJBAPOoz4xGjZHnYk1gUfhTVSxADupFVZHQK/VS55r9bnnG8dw8jv+B
XrOIcYRfJpgwDXBCcwc3MRJOPP52UPCEH98CQQDQDt1r9ariJgQmK+Tie/353qxzqeCPo2InSd5V
N1BaQ+JumDD7U2qUnzwMVxBBfEmtng3M4WBj+Xvq20bNKljxAkEArbI2mnolK9C13BEA/jRxsETO
HSVmFbc/zvfV0UA/BCLVgbnN+si/uN5YhhPKkI0Y12EXXRp0KeeKRaAUnRCjIwJASwvBlEplm/Lo
djhI8+SThIhsHcA9rrHZGqDLYGN2SUjJKOkeadj5zafuCelxhJ1nGgezpJ36nbUEnH8Bd8l5kQJA
erwu826+f+/9uhFryTW0NKBbh0d4nfZpwE95bUQIzdTPwL5reBsPeZWPC4GKAUsuNVycJcJpuRuO
0EWGEz/S8w==

公钥加密——私钥解密
加密前: abc

解密后: abc
公钥: 

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCWqz0Fc8hcXNpT+uotIdOoskHb69k1VmSpmRvr
BFz3orrA7GtVUYACjtgfUdfz7tWGD1bF5fTKYRQMZ0e3Aij3oBa990YPGlBzSk3zYkGZvSPqRAOM
fjOb4EjfXPkOUv2aijlSNs0SNvGmJ1s9g7Zdaq8eO+9gk20VNusYriGxzwIDAQAB

私钥: 

MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJarPQVzyFxc2lP66i0h06iyQdvr
2TVWZKmZG+sEXPeiusDsa1VRgAKO2B9R1/Pu1YYPVsXl9MphFAxnR7cCKPegFr33Rg8aUHNKTfNi
QZm9I+pEA4x+M5vgSN9c+Q5S/ZqKOVI2zRI28aYnWz2Dtl1qrx4772CTbRU26xiuIbHPAgMBAAEC
gYAYBH36s4U56/dFsdbIkP7bgmbrNsJuNTJgsq53nT9wnjkk7csCU7aTMdAT1gkVsnnJIALWEx0d
cbIvc/tDmg2LhB8/HuzW0o7OjxDjk4rKbod70tLbqz7DyzZkG6BsHatqNEO1rOzo1unFD6t9gIlQ
rWwJAAVyWEMYyh3aLDyckQJBAOnyl3vZyvolQ0wVTLOu4IrF6lkCX42AbXOJIST7C8YcqUCr1VLG
6sLmvBAvwyvslOLbNPsCtMNW3OrG/S+dGjcCQQCk3wqRLxvUjnPykhPKYH1S9d7tXWYhrJBrX0jw
ZrM5/bCHhuwNfv4FMXX6C3h629zNZ0vVm5OJLx2IevHbz/kpAkEAg6aQuJGHN91gUaBq2XK/yVg2
2IANZYOwFCRHEphzt7jJRitskHiAA830Zud53W31GvRgjCCpuINZLoVsVS8DYQJBAIR2y3ewgMy7
k37uTMZJ1gdEklLlurwNeI88JE86RH+wSxfomFmTkaY8ggxfEPKtGW9SsgQylkwfNbxFA3NXWlkC
QAhCygbyrAUrHhU7W8NOM9NghkbD0OACpHDuuK0VwJhlWQ8Hv8JUYMFJah/koGJXmGzKynCmH/1S
h+SYwehIkpM=

私钥加密——公钥解密
加密前: sign

解密后: sign
私钥签名——公钥验证签名
签名:
CXyvfEb4+KLS0PDbjyPbXjVHMkNBCOrpEhc1M/ZA3tWJ4PR509/QLsrzTUy7eaynFdqMqqB6sp7M
OQr1EDjN4WsEW1nObJfRvSX3Hz7CVwlYNHFaLIVbOvOjUDOTenNhVuK03MgfD29WA23L/AOU6hCi
P08X5DJnIqF//sN6R/Q=

状态:
true
 
分享到:
评论
1 楼 李永 2014-04-30  
[size=xx-small][align=left]
[flash=200,200][url][img][list]
[*]
引用
[u][i][/i][/u]
[/list][/img][/url][/flash]
[/align][/size]

相关推荐

    Java加密技术非对称加密算法RSA.doc

    Java加密技术非对称加密算法RSA.doc

    Java加密技术介绍.docx

    Java加密技术(四)——非对称加密算法RSA Java加密技术(五)——非对称加密算法的由来DH Java加密技术(六)——数字签名算法DSA Java加密技术(七)——非对称加密算法最高级ECC Java加密技术(八)——数字证书 ...

    Java加密技术详解(参考文档)

    在非对称加密部分,以RSA加密算法为例,介绍了如何在Java中实现非对称加密,包括密钥生成、公钥和私钥的获取以及加密和解密过程。通过本文的学习,读者可以掌握Java中的加密技术,确保数据的安全传输和存储。

    Java非对称加密_java_

    Java非对称加密源程序代码,使用RSA加密技术,定义加密算法可用 DES

    Java毕业设计-基于JAVA的RSA文件加密软件的设计与实现(源代码+论文).rar

    **基于Java的RSA文件加密软件的设计与实现** ...* Java学习者:通过学习和实践本项目,可以掌握RSA非对称加密算法的原理和应用。 * 软件开发者:可作为加密模块嵌入到其他Java应用中,提高数据安全性。

    Java加密与解密的艺术配书源代码

    对称加密网络应用242 7.8 小结254 第8章高等数据加密—非对称加密算法256 8.1 非对称加密算法简述256 8.2 密钥交换算法—DH 258 8.3 典型非对称加密算法—RSA 269 8.4 常用非对称加密算法—ElGamal277 8.5 实例:非...

    Java加密与解密的艺术

    对称加密网络应用2427.8 小结254第8章高等数据加密—非对称加密算法2568.1 非对称加密算法简述2568.2 密钥交换算法—DH 2588.3 典型非对称加密算法—RSA 2698.4 常用非对称加密算法—ElGamal2778.5 实例:非对称加密...

    Java非对称加密源码实例

    摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)...

    Java常见加密技术全景展示_附Java代码实现

    复杂的对称加密(DES、PBE)、非对称加密算法: ● DES(Data Encryption Standard,数据加密算法) ● PBE(Password-based encryption,基于密码验证) ● RSA(算法的名字以发明者的名字命名:Ron Rivest, ...

    java源码包---java 源码 大量 实例

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    RSA实验报告.docx

    例如RSA算法的安全性是建立在"大数分解和素性检测"这个数论难题的基础上,已知两个大素数a和b,求出a*b是容易计算的,而已知a*b,想知道其是哪两个大素数的乘积目前还没有好的计算方法,另外也有一些非对称加密算法...

    java源码包4

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    java源码包3

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    java源码包2

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    JAVA上百实例源码以及开源项目

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    JAVA上百实例源码以及开源项目源代码

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    JAVA上百实例源码以及开源项目源代码 java开源包2

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。 设定字符串为“张三,你好,我是李四”...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。 设定字符串为“张三,你好,我是李四”...

Global site tag (gtag.js) - Google Analytics