RSA加解密及签名的用法

加密分为对称加密非对称加密不可逆加密

对称加密
描述: 加密解密使用同样的密钥。
特点: 速度快,安全性一般。
举例:DES、3DES、AES
使用场景:对大量数据进行加解密。
非对称加密:
描述:加解密使用不同的密钥。
特点:速度慢,安全性较高。
举例:RSA
使用场景:在对称加密前,使用非对称加密传输公共的密钥。
不可逆加密:
描述:只能加密,不能解密,加密过程不可逆。
特点:不可逆加密。
举例:md5
使用场景:使用md5(md5(password)),使用双重不可逆加密对用户密码加密,并存入数据库。在验证用户密码的时候,将待验证的数据进行双重加密后与数据库中的数据作比较即可。

RSA加解密

RSA元素:
公钥:发给对方
私钥:自己保留
说明:
a 公钥加密后,私钥可以解密。
b 私钥加密后公钥可以解密。
c 私钥签名后,公钥可以验签。
d 密钥长度一般有:1024bits(128bytes) 2048bits(256bytes) 3072bits 4096bits。
e 密文长度一般等于密钥长度。(128bytes 256bytes)
f 待加密数据的长度:
RSA_PKCS1_PADDING RSA_size(128bytes) - 11 padding(11bytes) =117bytes
RSA_NO_PADDING RSA_size(128bytes) - 0 = 128bytes
RSA_X931_PADDING RSA_size(128bytes) - 2 padding(2bytes) = 126bytes
常用用法:
a. 公钥加密,私钥解密。
b. 私钥加密并签名,公钥验签并解密。
常见问题:
RSA对待加密的数据有长度限制(Data must not be longer than 117 bytes),需要分块加密。
实际应用场景:
1--通信双方A和B各自生成一对密钥对(公钥,私钥)。
2--A和B交换公钥。
3--根据DH算法计算出一个A和B共有的共享密钥
(原理:shareKey = A_privateKey * B_publicKey = A_publicKey * B_privateKey)。这只是示意,实际的DH运算是:
设有这么一个二元组 (q, p) = (3, 7)
我们定义Alice和Bob这么一个运算:
(1)Alice 选择一个范围在[1, p-1]的随机数,为da= 5
(2)Alice 计算Pa = q^da mod p = 3^5 mod 7 = 5
(3)Bob选择一个范围在[1, p-1]的随机数,为db = 6
(4)Bob计算Pb = q^db mod p = 3^6 mod 7 = 1
(5)Alice和Bob交换Pa和Pb
(6)Alice计算共享密钥S = Pb ^da mod p = 1^5 mod 7 = 1
(7)Bob计算共享密钥S = Pa ^db mod p = 5^6 m 7 = 1
4--使用shareKey来进行对称加密。
有证书应用场景:
1--通信双方A和B各自生成一对密钥对(公钥,私钥)。
2--使用证书系统根私钥对公钥进行签名生成公钥证书A和公钥证书B。
3--A,B交换公钥证书。
4--A和B使用证书系统根证书对公钥证书进行验签。
5--验签通过后提取公钥。
6--根据DH算法计算出一个A和B共有的共享密钥
(原理:shareKey = A_privateKey * B_publicKey = A_publicKey * B_privateKey)。
7--使用shareKey来进行对称加密。

RSA 加解密实例程序

代码:

依赖第三方类库:javabase64-1.3.1.jar
下载地址:https://sourceforge.net/projects/java-base64/files/

Base64Utils.java

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
 
import it.sauronsoftware.base64.Base64;
 
/** *//**
 * <p>
 * BASE64编码解码工具包
 * </p>
 * <p>
 * 依赖javabase64-1.3.1.jar
 * </p>
 * 
 * @author IceWee
 * @date 2012-5-19
 * @version 1.0
 */
public class Base64Utils {
 
    /** *//**
     * 文件读取缓冲区大小
     */
    private static final int CACHE_SIZE = 1024;
    
    /** *//**
     * <p>
     * BASE64字符串解码为二进制数据
     * </p>
     * 
     * @param base64
     * @return
     * @throws Exception
     */
    public static byte[] decode(String base64) throws Exception {
        return Base64.decode(base64.getBytes());
    }
    
    /** *//**
     * <p>
     * 二进制数据编码为BASE64字符串
     * </p>
     * 
     * @param bytes
     * @return
     * @throws Exception
     */
    public static String encode(byte[] bytes) throws Exception {
        return new String(Base64.encode(bytes));
    }
    
    /** *//**
     * <p>
     * 将文件编码为BASE64字符串
     * </p>
     * <p>
     * 大文件慎用,可能会导致内存溢出
     * </p>
     * 
     * @param filePath 文件绝对路径
     * @return
     * @throws Exception
     */
    public static String encodeFile(String filePath) throws Exception {
        byte[] bytes = fileToByte(filePath);
        return encode(bytes);
    }
    
    /** *//**
     * <p>
     * BASE64字符串转回文件
     * </p>
     * 
     * @param filePath 文件绝对路径
     * @param base64 编码字符串
     * @throws Exception
     */
    public static void decodeToFile(String filePath, String base64) throws Exception {
        byte[] bytes = decode(base64);
        byteArrayToFile(bytes, filePath);
    }
    
    /** *//**
     * <p>
     * 文件转换为二进制数组
     * </p>
     * 
     * @param filePath 文件路径
     * @return
     * @throws Exception
     */
    public static byte[] fileToByte(String filePath) throws Exception {
        byte[] data = new byte[0];
        File file = new File(filePath);
        if (file.exists()) {
            FileInputStream in = new FileInputStream(file);
            ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
            byte[] cache = new byte[CACHE_SIZE];
            int nRead = 0;
            while ((nRead = in.read(cache)) != -1) {
                out.write(cache, 0, nRead);
                out.flush();
            }
            out.close();
            in.close();
            data = out.toByteArray();
         }
        return data;
    }
    
    /** *//**
     * <p>
     * 二进制数据写文件
     * </p>
     * 
     * @param bytes 二进制数据
     * @param filePath 文件生成目录
     */
    public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {
        InputStream in = new ByteArrayInputStream(bytes);   
        File destFile = new File(filePath);
        if (!destFile.getParentFile().exists()) {
            destFile.getParentFile().mkdirs();
        }
        destFile.createNewFile();
        OutputStream out = new FileOutputStream(destFile);
        byte[] cache = new byte[CACHE_SIZE];
        int nRead = 0;
        while ((nRead = in.read(cache)) != -1) {   
            out.write(cache, 0, nRead);
            out.flush();
        }
        out.close();
        in.close();
    }
    
    
}
 

RSAUtils.java

改进点:
1 增加了try catch ,不用将异常抛出。这样可以给类的变量赋值。生成密钥对的时候使用。
2 增加了将公钥和私钥存储到文件的功能。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
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.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

/** *//**
* <p>
* RSA公钥/私钥/签名工具包
* </p>
* <p>
* 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman)
* </p>
* <p>
* 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/>
* 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>
* 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
* </p>
* 
* @author IceWee
* @date 2012-4-26
* @version 1.0
*/
public class RSAUtils {

   /** *//**
    * 加密算法RSA
    */
   public static final String KEY_ALGORITHM = "RSA";
   
   /** *//**
    * 签名算法
    */
   public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

   /** *//**
    * 获取公钥的key
    */
   private static final String PUBLIC_KEY = "RSAPublicKey";
   
   /** *//**
    * 获取私钥的key
    */
   private static final String PRIVATE_KEY = "RSAPrivateKey";
   
   /** *//**
    * RSA最大加密明文大小
    */
   private static final int MAX_ENCRYPT_BLOCK = 117;
   
   /** *//**
    * RSA最大解密密文大小
    */
   private static final int MAX_DECRYPT_BLOCK = 128;


   /** *//**
    * <p>
    * 生成密钥对(公钥和私钥)
    * </p>
    * 
    * @return
    * @throws Exception
    */
   public static Map<String, Object> genKeyPair()  {
       try {
        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;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
   }
   
   /** *//**
    * <p>
    * 用私钥对信息生成数字签名
    * </p>
    * 
    * @param data 已加密数据
    * @param privateKey 私钥(BASE64编码)
    * 
    * @return
    * @throws Exception
    */
   public static String sign(byte[] data, String privateKey)   {
       try {
        byte[] keyBytes = Base64Utils.decode(privateKey);
           PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
           KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
           PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
           Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
           signature.initSign(privateK);
           signature.update(data);
           return Base64Utils.encode(signature.sign());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       return null;
   }

   /** *//**
    * <p>
    * 校验数字签名
    * </p>
    * 
    * @param data 已加密数据
    * @param publicKey 公钥(BASE64编码)
    * @param sign 数字签名
    * 
    * @return
    * @throws Exception
    * 
    */
   public static boolean verify(byte[] data, String publicKey, String sign)
           throws Exception {
       byte[] keyBytes = Base64Utils.decode(publicKey);
       X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
       KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
       PublicKey publicK = keyFactory.generatePublic(keySpec);
       Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
       signature.initVerify(publicK);
       signature.update(data);
       return signature.verify(Base64Utils.decode(sign));
   }

   /** *//**
    * <P>
    * 私钥解密
    * </p>
    * 
    * @param encryptedData 已加密数据
    * @param privateKey 私钥(BASE64编码)
    * @return
    * @throws Exception
    */
   public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)
   {
       try {
        byte[] keyBytes = Base64Utils.decode(privateKey);
           PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
           KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
           Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
           Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
           cipher.init(Cipher.DECRYPT_MODE, privateK);
           int inputLen = encryptedData.length;
           ByteArrayOutputStream out = new ByteArrayOutputStream();
           int offSet = 0;
           byte[] cache;
           int i = 0;
           // 对数据分段解密
           while (inputLen - offSet > 0) {
               if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                   cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
               } else {
                   cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
               }
               out.write(cache, 0, cache.length);
               i++;
               offSet = i * MAX_DECRYPT_BLOCK;
           }
           byte[] decryptedData = out.toByteArray();
           out.close();
           return decryptedData;
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       return null;
   }

   /** *//**
    * <p>
    * 公钥解密
    * </p>
    * 
    * @param encryptedData 已加密数据
    * @param publicKey 公钥(BASE64编码)
    * @return
    * @throws Exception
    */
   public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)
   {
       try {
        byte[] keyBytes = Base64Utils.decode(publicKey);
           X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
           KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
           Key publicK = keyFactory.generatePublic(x509KeySpec);
           Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
           cipher.init(Cipher.DECRYPT_MODE, publicK);
           int inputLen = encryptedData.length;
           ByteArrayOutputStream out = new ByteArrayOutputStream();
           int offSet = 0;
           byte[] cache;
           int i = 0;
           // 对数据分段解密
           while (inputLen - offSet > 0) {
               if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                   cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
               } else {
                   cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
               }
               out.write(cache, 0, cache.length);
               i++;
               offSet = i * MAX_DECRYPT_BLOCK;
           }
           byte[] decryptedData = out.toByteArray();
           out.close();
           return decryptedData;
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       return null;
   }

   /** *//**
    * <p>
    * 公钥加密
    * </p>
    * 
    * @param data 源数据
    * @param publicKey 公钥(BASE64编码)
    * @return
    * @throws Exception
    */
   public static byte[] encryptByPublicKey(byte[] data, String publicKey)
   {

        try {
            byte[] keyBytes = Base64Utils.decode(publicKey);
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key publicK = keyFactory.generatePublic(x509KeySpec);
            // 对数据加密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, publicK);
            int inputLen = data.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段加密
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                    cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(data, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_ENCRYPT_BLOCK;
            }
            byte[] encryptedData = out.toByteArray();
            out.close();
            return encryptedData;
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
   }

   /** *//**
    * <p>
    * 私钥加密
    * </p>
    * 
    * @param data 源数据
    * @param privateKey 私钥(BASE64编码)
    * @return
    * @throws Exception
    */
   public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
   {
        try {
            byte[] keyBytes = Base64Utils.decode(privateKey);
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, privateK);
            int inputLen = data.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段加密
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                    cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(data, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_ENCRYPT_BLOCK;
            }
            byte[] encryptedData = out.toByteArray();
            out.close();
            return encryptedData;
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       return null;
   }

   /** *//**
    * <p>
    * 获取私钥
    * </p>
    * 
    * @param keyMap 密钥对
    * @return
    * @throws Exception
    */
   public static String getPrivateKey(Map<String, Object> keyMap)
   {
        try {
            Key key = (Key) keyMap.get(PRIVATE_KEY);
            return Base64Utils.encode(key.getEncoded());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       return null;
   }

   /** *//**
    * <p>
    * 获取公钥
    * </p>
    * 
    * @param keyMap 密钥对
    * @return
    * @throws Exception
    */
   public static String getPublicKey(Map<String, Object> keyMap)
   {
        try {
            Key key = (Key) keyMap.get(PUBLIC_KEY);
            return Base64Utils.encode(key.getEncoded());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
   }
  
   /** *//**
    * <p>
    * 获取私钥
    * </p>
    * 
    * @param privateKeystore 读取存储私钥的文件
    * @return
    * @throws Exception
    */
   public static String readPrivateKeyFile(String privateKeystore)
   {
       
        try {
            StringBuilder privateKey = new StringBuilder();
            FileReader fr = new FileReader(privateKeystore);
            BufferedReader br = new BufferedReader(fr);

            String line;
            while ((line = br.readLine()) != null) {
                privateKey.append(line);
            }
            br.close();
            fr.close();

            return privateKey.toString();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
   }
   
   /** *//**
    * <p>
    * 获取公钥
    * </p>
    * 
    * @param publicKeystore 存储公钥的文件
    * @return
    * @throws Exception
    */
   public static String readPublicKeyFile(String publicKeystore)
   {
        try {
            StringBuilder publicKey = new StringBuilder();
            FileReader fr = new FileReader(publicKeystore);
            BufferedReader br = new BufferedReader(fr);
            String line;
            while ((line = br.readLine()) != null) {
                publicKey.append(line);
            }
            br.close();
            fr.close();

            return publicKey.toString();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
   }
   
   /** *//**
    * <p>
    *  存储私钥到文件
    * </p>
    * 
    * @param privateKey      私钥字符串
    * @param privateKeystore 存储私钥的文件
    * @return
    * @throws Exception
    */
   public static void writePrivateKeyFile(String  privateKey, String privateKeystore)
   {
        try {
            FileWriter fw = new FileWriter(privateKeystore);
            fw.write(privateKey);
            fw.flush();
            fw.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
   }
   
   /** *//**
    * <p>
    * 存储公钥到文件
    * </p>
    * 
    * @param publicKey 公钥文件
    * @param publicKeystore 存储公钥的文件
    * @return
    * @throws Exception
    */
   public static void writePublicKeyFile(String publicKey, String publicKeystore)
   {
        try {
            FileWriter fw = new FileWriter(publicKeystore);
            fw.write(publicKey);
            fw.flush();
            fw.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
   }
   
   public static void testEncryptAndSignByPrivateKey(String publicKey, String privateKey) {
       System.err.println("私钥加密<===>公钥解密");
       String source = "1. 这是测试通过私钥加密,公钥解密的测试源数据" + 
                       "2. 这是测试通过私钥加密,公钥解密的测试源数据" +
                       "3. 这是测试通过私钥加密,公钥解密的测试源数据" +
                       "4. 这是测试通过私钥加密,公钥解密的测试源数据" +
                       "5. 这是测试通过私钥加密,公钥解密的测试源数据" +
                       "6. 这是测试通过私钥加密,公钥解密的测试源数据" +
                       "7. 这是测试通过私钥加密,公钥解密的测试源数据" +
                       "8. 这是测试通过私钥加密,公钥解密的测试源数据" +
                       "9. 这是测试通过私钥加密,公钥解密的测试源数据" +
                       "10. 这是测试通过私钥加密,公钥解密的测试源数据" 
                       ;
       System.out.println("加密前的数据:\r\n" + source);
       byte[] data = source.getBytes();
       try {
           
           byte[] encodeData = RSAUtils.encryptByPrivateKey(data, privateKey);
           System.out.println("加密后的数据:\r\n" + new String(encodeData));
           byte[] decodeData = RSAUtils.decryptByPublicKey(encodeData, publicKey);
           System.out.println("解密后的数据: \r\n" + new String(decodeData));
           System.err.println("私钥签名<===>公钥验签");
           String sign = RSAUtils.sign(decodeData, privateKey);
           System.out.println("签名数据: \r\n" + sign);
           boolean status = RSAUtils.verify(decodeData, publicKey, sign);
           System.out.println("验签结果:\r\n" + status);
           
       } catch (Exception e) {
            // TODO: handle exception
           e.printStackTrace();
       }
   }

public static void testEncryptByPublicKey(String publicKey, String privateKey) {
       System.err.println("公钥加密<===>私钥解密");
       String source = "这是测试公钥加密,私钥解密的测试源数据";
       System.out.println("加密前的数据:\r\n" + source);
//       byte[] data = source.getBytes();
       
       try {
           byte[] data = source.getBytes();
           byte[] encodedData = RSAUtils.encryptByPublicKey(data, publicKey);
           System.out.println("加密后的数据: \r\n" + new String(encodedData));
           
           byte[] decodedData = RSAUtils.decryptByPrivateKey(encodedData, privateKey);
           System.out.println("解密后的数据: \r\n" + new String(decodedData));
       } catch (Exception e) {
        // TODO Auto-generated catch block
           e.printStackTrace();
       }
   }


   public static void main(String[] args) {
       
       String publicKey;
       String privateKey;
       
       try {
           
           Map<String, Object> keyMap = RSAUtils.genKeyPair();
           publicKey = RSAUtils.getPublicKey(keyMap);
           privateKey = RSAUtils.getPrivateKey(keyMap);
           System.err.println("PublicKey: \r\n" + publicKey);
           System.err.println("PrivateKey: \r\n" + privateKey);
           
           Thread.sleep(100);
           testEncryptByPublicKey(publicKey, privateKey);
           Thread.sleep(100);
           testEncryptAndSignByPrivateKey(publicKey, privateKey);
           
           System.err.println("测试存储公钥文件: ");
           String publicKeystore = "D:\\test\\RSA\\publicKey.store";
           writePublicKeyFile(publicKey, publicKeystore);
           System.out.println("write ok");
           Thread.sleep(100);
           System.err.println("测试读取公钥文件: ");
           String readPublicKey = readPublicKeyFile(publicKeystore);
           System.out.println("读取的公钥文件:\r\n" + readPublicKey);
           
       } catch (Exception e) {
        // TODO: handle exception
           e.printStackTrace();
       }
           
   }

}


程序运行结果:

image.png

image.png

参考

DH算法:
https://blog.csdn.net/y_xianjun/article/details/81327943
MD5与对称加密、非对称加密算法的比较:
https://blog.csdn.net/wangpeng322/article/details/84106548
java对称加密与非对称加密(DES、AES、RSA的实现):
https://blog.csdn.net/chengbinbbs/article/details/78640589
RSA密钥长度、明文长度和密文长度
https://blog.csdn.net/luoluo_onion/article/details/78354799

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容