当前位置:天才代写 > tutorial > JAVA 教程 > Java加密技能(四)

Java加密技能(四)

2017-11-11 08:00 星期六 所属: JAVA 教程 浏览:461

副标题#e#

接下来我们先容典范的非对称加密算法——RSA

RSA

这种算法1978年就呈现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于领略和操纵,也很风行。算法的名字以发现者的名字定名:Ron Rivest, AdiShamir 和Leonard Adleman。

这种加密算法的特点主要是密钥的变革,上文我们看到DES只有一个密钥。相当于只有一把钥匙,假如这把钥匙丢了,数据也就不安详了。RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据举办校验。确保数据在传输工程中不被修改。

流程阐明:

甲方构建密钥对儿,将公钥发布给乙方,将私钥保存。

甲方利用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方利用公钥、签名来验证待解密数据是否有效,假如有效利用公钥对数据解密。

乙方利用公钥加密数据,向甲方发送颠末加密后的数据;甲方得到加密数据,通过私钥解密。

按如上步调给出序列图,如下:

Java加密技术(四)

Java加密技术(四)

Java加密技术(四)


#p#副标题#e#

通过java代码实现如下:Coder类见 Java加密技能(一)

Java代码

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 梁栋
  * @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;
     }
}

#p#副标题#e#

再给出一个测试类:

#p#分页标题#e#

Java代码

import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import java.util.Map;
/** *//**
 *
 * @author 梁栋  http://www.bt285.cn  http://www.guihua.org
 * @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);
    }
}

#p#副标题#e#

节制台输出:

Console代码

#p#分页标题#e#

公钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYU/+I0+z1aBl5X6DUUOHQ7FZpmBSDbKTtx89J
EcB64jFCkunELT8qiKly7fzEqD03g8ALlu5XvX+bBqHFy7YPJJP0ekE2X3wjUnh2NxlqpH3/B/xm
1ZdSlCwDIkbijhBVDjA/bu5BObhZqQmDwIxlQInL9oVz+o6FbAZCyHBd7wIDAQAB
私钥:
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJhT/4jT7PVoGXlfoNRQ4dDsVmmy
FINspO3Hz0kRwHriMUKS6cQtPyqIqXLt/MSoPTeDwAuW7le9f5sGocXLtg8kk/R6QTZffCNSeHY3
GWqkff8H/GbVl1KULAMiRuKOEFUOMD9u7kE5uFmpCYPAjGVAicv2hXP6joVsBkLIcF3vAgMBAAEC
gYBvZHWoZHmS2EZQqKqeuGr58eobG9hcZzWQoJ4nq/CarBAjw/VovUHE490uK3S9ht4FW7Yzg3LV
/MB06Huifh6qf/X9NQA7SeZRRC8gnCQk6JuDIEVJOud5jU+9tyumJakDKodQ3Jf2zQtNr+5ZdEPl
uwWgv9c4kmpjhAdyMuQmYQJBANn6pcgvyYaia52dnu+yBUsGkaFfwXkzFSExIbi0MXTkhEb/ER/D
rLytukkUu5S5ecz/KBa8U4xIslZDYQbLz5ECQQCy5dutt7RsxN4+dxCWn0/1FrkWl2G329Ucewm3
QU9CKu4D+7Kqdj+Ha3lXP8F0Etaaapi7+EfkRUpukn2ItZV/AkEAlk+I0iphxT1rCB0Q5CjWDY5S
Df2B5JmdEG5Y2o0nLXwG2w44OLct/k2uD4cEcuITY5Dvi/4BftMCZwm/dnhEgQJACIktJSnJwxLV
o9dchENPtlsCM9C/Sd2EWpqISSUlmfugZbJBwR5pQ5XeMUqKeXZYpP+HEBj1nS+tMH9u2/IGEwJa
fL8mZiZXan/oBKrblAbplNcKWGRVD/3y65042PAEeghahlJMiYquV5DzZajuuT0wbJ5xQuZB01+X
nfpFpBJ2dw==
公钥加密——私钥解密
加密前: abc
解密后: abc
公钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdOj40yEB48XqWxmPILmJAc7UecIN7F32etSHF
9rwbuEh3+iTPOGSxhoSQpOED0vOb0ZIMkBXZSgsxLaBSin2RZ09YKWRjtpCA0kDkiD11gj4tzTiM
l9qq1kwSK7ZkGAgodEn3yIILVmQDuEImHOXFtulvJ71ka07u3LuwUNdB/wIDAQAB
私钥:
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN06PjTIQHjxepbGY8guYkBztR5w
g3sXfZ61IcX2vBu4SHf6JM84ZLGGhJCk4QPS85vRkgyQFdlKCzEtoFKKfZFnT1gpZGO2kIDSQOSI
PXWCPi3NOIyX2qrWTBIrtmQYCCh0SffIggtWZAO4QiYc5cW26W8nvWRrTu7cu7BQ10H/AgMBAAEC
gYEAz2JWBizjI31bqhP4XiP9PuY5F3vqBW4T+L9cFbQiyumKJc58yzTWUAUGKIIn3enXLG7dNqGr
mbJro4JeFIJ3CiVDpXR9+FluIgI4SXm7ioGKF2NOMA9LR5Fu82W+pLfpTN2y2SaLYWEDZyp53Bxy
j9gUxaxi1MQs+C1ZgDF2xmECQQDy70bQntbRfysP+ppCtd56YRnES1Tyekw0wryS2tr+ivQJl7JF
gp5rPAOXpgrq36xHDwUspQ0sJ0vj0O7ywxr1AkEA6SAaLhrJJrYucC0jxwAhUYyaPN+aOsWymaRh
9jA/Wc0wp29SbGTh5CcMuGpXm1g0M+FKW3dGiHgS3rVUKim4owJAbnxgapUzAgiiHxxMeDaavnHW
9C2GrtjsO7qtZOTgYI/1uT8itvZW8lJTF+9OW8/qXE76fXl7ai9dFnl5kzMk2QJBALfHz/vCsArt
mkRiwY6zApE4Z6tPl1V33ymSVovvUzHnOdD1SKQdD5t+UV/crb3QVi8ED0t2B0u0ZSPfDT/D7kMC
QDpwdj9k2F5aokLHBHUNJPFDAp7a5QMaT64gv/d48ITJ68Co+v5WzLMpzJBYXK6PAtqIhxbuPEc2
I2k1Afmrwyw=
私钥加密——公钥解密
加密前: sign
解密后: sign
私钥签名——公钥验证签名
签名:
ud1RsIwmSC1pN22I4IXteg1VD2FbiehKUfNxgVSHzvQNIK+d20FCkHCqh9djP3h94iWnIUY0ifU+
mbJkhAl/i5krExOE0hknOnPMcEP+lZV1RbJI2zG2YooSp2XDleqrQk5e/QF2Mx0Zxt8Xsg7ucVpn
i3wwbYWs9wSzIf0UjlM=
状态:
true

#p#分页标题#e#

扼要总结一下,利用公钥加密、私钥解密,完成了乙方到甲方的一次数据通报,通过私钥加密、公钥解密,同时通过私钥签名、公钥验证签名,完成了一次甲方到乙方的数据通报与验证,两次数据通报完成一整套的数据交互!

 

    关键字:

天才代写-代写联系方式