RSA加密与解密

xiaoxiao2021-02-27  277

package utils;   [html]  view plain  copy import java.io.ByteArrayOutputStream;   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;      /**    * <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() 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>        * 用私钥对信息生成数字签名        * </p>        *         * @param data        *            已加密数据        * @param privateKey        *            私钥(BASE64编码)        *         * @return        * @throws Exception        */       public static String sign(byte[] data, String privateKey) throws Exception {           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());       }          /**        * <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) throws Exception {           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;       }          /**        * <p>        * 公钥解密        * </p>        *         * @param encryptedData        *            已加密数据        * @param publicKey        *            公钥(BASE64编码)        * @return        * @throws Exception        */       public static byte[] decryptByPublicKey(byte[] encryptedData,               String publicKey) throws Exception {           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;       }          /**        * <p>        * 公钥加密        * </p>        *         * @param data        *            源数据        * @param publicKey        *            公钥(BASE64编码)        * @return        * @throws Exception        */       public static byte[] encryptByPublicKey(byte[] data, String publicKey)               throws Exception {           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;       }          /**        * <p>        * 私钥加密        * </p>        *         * @param data        *            源数据        * @param privateKey        *            私钥(BASE64编码)        * @return        * @throws Exception        */       public static byte[] encryptByPrivateKey(byte[] data, String privateKey)               throws Exception {           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;       }          /**        * <p>        * 获取私钥        * </p>        *         * @param keyMap        *            密钥对        * @return        * @throws Exception        */       public static String getPrivateKey(Map<String, Object> keyMap)               throws Exception {           Key key = (Key) keyMap.get(PRIVATE_KEY);           return Base64Utils.encode(key.getEncoded());       }          /**        * <p>        * 获取公钥        * </p>        *         * @param keyMap        *            密钥对        * @return        * @throws Exception        */       public static String getPublicKey(Map<String, Object> keyMap)               throws Exception {           Key key = (Key) keyMap.get(PUBLIC_KEY);           return Base64Utils.encode(key.getEncoded());       }      }  

Base64Utils文件

[html]  view plain  copy package utils;      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 com.sun.org.apache.xml.internal.security.utils.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();       }                 }  

测试用例:

[html]  view plain  copy package util;         import java.util.Map;      import RSAUtils;      public class RSATester {          static String publicKey;       static String privateKey;          static {           try {               Map<String, Object> keyMap = RSAUtils.genKeyPair();               publicKey = RSAUtils.getPublicKey(keyMap);               privateKey = RSAUtils.getPrivateKey(keyMap);               System.err.println("公钥: \n\r" + publicKey);               System.err.println("私钥: \n\r" + privateKey);           } catch (Exception e) {               e.printStackTrace();           }       }              public static void main(String[] args) throws Exception {           test();           testSign();       }          static void test() throws Exception {           System.err.println("公钥加密——私钥解密");           String source = "这是一行没有任何意义的文字,你看完了等于没看,不是吗?";           System.out.println("\r加密前文字:\r\n" + source);           byte[] data = source.getBytes();           byte[] encodedData = RSAUtils.encryptByPublicKey(data, publicKey);           System.out.println("加密后文字:\r\n" + new String(encodedData));           byte[] decodedData = RSAUtils.decryptByPrivateKey(encodedData, privateKey);           String target = new String(decodedData);           System.out.println("解密后文字: \r\n" + target);       }          static void testSign() throws Exception {           System.err.println("私钥加密——公钥解密");           String source = "这是一行测试RSA数字签名的无意义文字";           System.out.println("原文字:\r\n" + source);           byte[] data = source.getBytes();           byte[] encodedData = RSAUtils.encryptByPrivateKey(data, privateKey);           System.out.println("加密后:\r\n" + new String(encodedData));           byte[] decodedData = RSAUtils.decryptByPublicKey(encodedData, publicKey);           String target = new String(decodedData);           System.out.println("解密后: \r\n" + target);           System.err.println("私钥签名——公钥验证签名");           String sign = RSAUtils.sign(encodedData, privateKey);           System.err.println("签名:\r" + sign);           boolean status = RSAUtils.verify(encodedData, publicKey, sign);           System.err.println("验证结果:\r" + status);       }          }  

生成RSA密钥、保存到文件、从文件读取、加密、解密等操作

[html]  view plain  copy 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.SecureRandom;      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 javax.crypto.Cipher;      import org.apache.commons.configuration.ConfigurationException;      import org.apache.commons.configuration.PropertiesConfiguration;      import org.bouncycastle.jce.provider.BouncyCastleProvider;           public class RSATest {               public static void main(String[] args) {              try {                  RSATest encrypt = new RSATest();                  String encryptText = "encryptText";                       // Generate keys                  KeyPair keyPair = encrypt.generateKey();                  RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();                  RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();                       byte[] e = encrypt.encrypt(publicKey, encryptText.getBytes());                  byte[] de = encrypt.decrypt(privateKey, e);                  System.out.println(toHexString(e));                  System.out.println(toHexString(de));              } catch (Exception e) {                  e.printStackTrace();              }          }               public KeyPair generateKey() throws NoSuchAlgorithmException {              KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");              keyPairGen.initialize(1024, new SecureRandom());                   KeyPair keyPair = keyPairGen.generateKeyPair();              return keyPair;          }               public void saveKey(KeyPair keyPair, String publicKeyFile,                  String privateKeyFile) throws ConfigurationException {              PublicKey pubkey = keyPair.getPublic();              PrivateKey prikey = keyPair.getPrivate();                   // save public key              PropertiesConfiguration publicConfig = new PropertiesConfiguration(                      publicKeyFile);              publicConfig.setProperty("PULIICKEY", toHexString(pubkey.getEncoded()));              publicConfig.save();                   // save private key              PropertiesConfiguration privateConfig = new PropertiesConfiguration(                      privateKeyFile);              privateConfig.setProperty("PRIVATEKEY",                      toHexString(prikey.getEncoded()));              privateConfig.save();          }               /**          * @param filename          * @param type:          *            1-public 0-private          * @return          * @throws ConfigurationException          * @throws NoSuchAlgorithmException          * @throws InvalidKeySpecException          */         public Key loadKey(String filename, int type)                  throws ConfigurationException, NoSuchAlgorithmException,                  InvalidKeySpecException {              PropertiesConfiguration config = new PropertiesConfiguration(filename);              KeyFactory keyFactory = KeyFactory.getInstance("RSA",                      new BouncyCastleProvider());                   if (type == 0) {                  // privateKey                  String privateKeyValue = config.getString("PULIICKEY");                  PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(                          toBytes(privateKeyValue));                  PrivateKey privateKey = keyFactory.generatePrivate(priPKCS8);                  return privateKey;                   } else {                  // publicKey                  String privateKeyValue = config.getString("PRIVATEKEY");                  X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(                          toBytes(privateKeyValue));                  PublicKey publicKey = keyFactory.generatePublic(bobPubKeySpec);                  return publicKey;              }          }               /**          * Encrypt String.          *           * @return byte[]          */         protected byte[] encrypt(RSAPublicKey publicKey, byte[] data) {              if (publicKey != null) {                  try {                      Cipher cipher = Cipher.getInstance("RSA",                              new BouncyCastleProvider());                      cipher.init(Cipher.ENCRYPT_MODE, publicKey);                      return cipher.doFinal(data);                  } catch (Exception e) {                      e.printStackTrace();                  }              }              return null;          }               /**          * Basic decrypt method          *           * @return byte[]          */         protected byte[] decrypt(RSAPrivateKey privateKey, byte[] raw) {              if (privateKey != null) {                  try {                      Cipher cipher = Cipher.getInstance("RSA",                              new BouncyCastleProvider());                      cipher.init(Cipher.DECRYPT_MODE, privateKey);                      return cipher.doFinal(raw);                  } catch (Exception e) {                      e.printStackTrace();                  }              }                   return null;          }               public static String toHexString(byte[] b) {              StringBuilder sb = new StringBuilder(b.length * 2);              for (int i = 0; i < b.length; i++) {                  sb.append(HEXCHAR[(b[i] & 0xf0) >>> 4]);                  sb.append(HEXCHAR[b[i] & 0x0f]);              }              return sb.toString();          }               public static final byte[] toBytes(String s) {              byte[] bytes;              bytes = new byte[s.length() / 2];              for (int i = 0; i < bytes.length; i++) {                  bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2),                          16);              }              return bytes;          }               private static char[] HEXCHAR = { '0', '1', '2', '3', '4', '5', '6', '7',                  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };           }  

Java中RSA非对称密钥加解密使用示例

一、简介:

  RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它。RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名。这个算法经受住了多年深入的密码分析,虽然密码分析者既不能证明也不能否定RSA的安全性,但这恰恰说明该算法有一定的可信性,目前它已经成为最流行的公开密钥算法。

  二、RSA的公钥、私钥的组成,以及加密、解密的公式可见于下表

  三、使用方式:

  ① 假设A、B机器进行通信,已A机器为主;

  ② A首先需要用自己的私钥为发送请求数据签名,并将公钥一同发送给B;

  ③ B收到数据后,需要用A发送的公钥进行验证,已确保收到的数据是未经篡改的;

  ④ B验签通过后,处理逻辑,并把处理结果返回,返回数据需要用A发送的公钥进行加密(公钥加密后,只能用配对的私钥解密);

  ⑤ A收到B返回的数据,使用私钥解密,至此,一次数据交互完成。

  四、代码示例:

  1、第一步获取私钥,为签名做准备。

[html]  view plain  copy /**        * 读取私钥  返回PrivateKey        * @param path  包含私钥的证书路径        * @param password  私钥证书密码        * @return 返回私钥PrivateKey        * @throws KeyStoreException        * @throws NoSuchAlgorithmException        * @throws CertificateException        * @throws IOException        * @throws UnrecoverableKeyException        */       private static PrivateKey getPrivateKey(String path,String password)               throws KeyStoreException, NoSuchAlgorithmException, CertificateException,               IOException, UnrecoverableKeyException {           KeyStore ks = KeyStore.getInstance("PKCS12");           FileInputStream fis = new FileInputStream(path);           char[] nPassword = null;           if ((password == null) || password.trim().equals("")) {               nPassword = null;           } else {               nPassword = password.toCharArray();           }           ks.load(fis, nPassword);           fis.close();           Enumeration<String> en = ks.aliases();           String keyAlias = null;           if (en.hasMoreElements()) {               keyAlias = (String) en.nextElement();           }               return (PrivateKey) ks.getKey(keyAlias, nPassword);       }  

2、签名示例:通过第一步得到的私钥,进行签名操作,具体请看以下代码:

[html]  view plain  copy /**        * 私钥签名: 签名方法如下:BASE64(RSA(MD5(src),privatekey)),其中src为需要签名的字符串,   privatekey是商户的CFCA证书私钥。        * @param plainText 待签名字符串        * @param path 签名私钥路径        * @param password  签名私钥密码        * @return 返回签名后的字符串        * @throws Exception        */       public static String sign(String plainText,String path,String password)               throws Exception  {           /*            * MD5加密            */           MessageDigest md5 = MessageDigest.getInstance("MD5");           md5.update(plainText.getBytes("utf-8"));           byte[] digestBytes = md5.digest();           /*            * 用私钥进行签名 RSA            * Cipher负责完成加密或解密工作,基于RSA            */           Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");           //ENCRYPT_MODE表示为加密模式           cipher.init(Cipher.ENCRYPT_MODE, getPrivateKey(path, password));           //加密           byte[] rsaBytes = cipher.doFinal(digestBytes);           //Base64编码           return Base64.byteArrayToBase64(rsaBytes);}  

3、B收到数据后,需要使用A提供的公钥信息进行验签,此处使用公钥的N、E进行验签

  首先通过公钥N、E得到公钥PublicKey,如下:

[html]  view plain  copy /**         * 根据公钥n、e生成公钥        * @param modulus   公钥n串        * @param publicExponent  公钥e串        * @return 返回公钥PublicKey        * @throws Exception        */       public static PublicKey getPublickKey(String modulus, String publicExponent)               throws Exception {           KeySpec publicKeySpec = new RSAPublicKeySpec(                   new BigInteger(modulus, 16), new BigInteger(publicExponent, 16));           KeyFactory factory = KeyFactory.getInstance("RSA");           PublicKey publicKey = factory.generatePublic(publicKeySpec);           return publicKey;       }   得到公钥PublicKey后,再去验证签名,代码如下:

[html]  view plain  copy /**        * 用公钥证书进行验签        * @param message  签名之前的原文        * @param cipherText  签名        * @param pubKeyn 公钥n串        * @param pubKeye 公钥e串        * @return boolean 验签成功为true,失败为false        * @throws Exception        */       public static boolean verify(String message, String cipherText,String pubKeyn,               String pubKeye) throws Exception {           Cipher c4 = Cipher.getInstance("RSA/ECB/PKCS1Padding");           // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示解密模式           c4.init(Cipher.DECRYPT_MODE, getPublickKey(pubKeyn,pubKeye));           // 解密           byte[] desDecTextBytes = c4.doFinal(Base64.base64ToByteArray(cipherText));           // 得到前置对原文进行的MD5           String md5Digest1 = Base64.byteArrayToBase64(desDecTextBytes);           MessageDigest md5 = MessageDigest.getInstance("MD5");           md5.update(message.getBytes("utf-8"));           byte[] digestBytes = md5.digest();           // 得到商户对原文进行的MD5           String md5Digest2 = Base64.byteArrayToBase64(digestBytes);           // 验证签名           if (md5Digest1.equals(md5Digest2)) {               return true;           } else {               return false;           }       }  

 至此,签名验签已经完毕

  4、提供一个从.cer文件读取公钥的方法:

[html]  view plain  copy /**        * 读取公钥cer        * @param path .cer文件的路径  如:c:/abc.cer        * @return  base64后的公钥串        * @throws IOException        * @throws CertificateException        */       public static String getPublicKey(String path) throws IOException,       CertificateException{           InputStream inStream = new FileInputStream(path);           ByteArrayOutputStream out = new ByteArrayOutputStream();           int ch;           String res = "";           while ((ch = inStream.read()) != -1) {               out.write(ch);           }           byte[] result = out.toByteArray();           res = Base64.byteArrayToBase64(result);           return res;       }  
转载请注明原文地址: https://www.6miu.com/read-4823.html

最新回复(0)