RSA公鑰私鑰加解密,驗籤

import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;

/**
* <p>
* 封裝同RSA非對稱加密算法有關的方法,可用於數字簽名,RSA加密解密
* </p>
* 
* @Copyright:WDSsoft
*/

public class RSATool {

public RSATool() {
}

/**使用私鑰加密數據
  * 用一個已打包成byte[]形式的私鑰加密數據,即數字簽名
  * 
  * @param keyInByte
  *            打包成byte[]的私鑰
  * @param source
  *            要簽名的數據,一般應是數字摘要
  * @return 簽名 byte[]
  */
public static byte[] sign(byte[] keyInByte, byte[] source) {
  try {
   PKCS8EncodedKeySpec priv_spec = new PKCS8EncodedKeySpec(keyInByte);
   KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
   PrivateKey privKey = mykeyFactory.generatePrivate(priv_spec);
   Signature sig = Signature.getInstance("SHA1withRSA");
   sig.initSign(privKey);
   sig.update(source);
   return sig.sign();
  } catch (Exception e) {
   return null;
  }
}

/**
  * 驗證數字簽名
  * 
  * @param keyInByte
  *            打包成byte[]形式的公鑰
  * @param source
  *            原文的數字摘要
  * @param sign
  *            簽名(對原文的數字摘要的簽名)
  * @return 是否證實 boolean
  */
public static boolean verify(byte[] keyInByte, byte[] source, byte[] sign) {
  try {
   KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
   Signature sig = Signature.getInstance("SHA1withRSA");
   X509EncodedKeySpec pub_spec = new X509EncodedKeySpec(keyInByte);
   PublicKey pubKey = mykeyFactory.generatePublic(pub_spec);
   sig.initVerify(pubKey);
   sig.update(source);
   return sig.verify(sign);
  } catch (Exception e) {
   return false;
  }
}

/**
  * 建立新的密鑰對,返回打包的byte[]形式私鑰和公鑰
  * 
  * @return 包含打包成byte[]形式的私鑰和公鑰的object[],其中,object[0]爲私鑰byte[],object[1]爲公鑰byte[]
  */
public static Object[] giveRSAKeyPairInByte() {
  KeyPair newKeyPair = creatmyKey();
  if (newKeyPair == null)
   return null;
  Object[] re = new Object[2];
  if (newKeyPair != null) {
   PrivateKey priv = newKeyPair.getPrivate();
   byte[] b_priv = priv.getEncoded();
   PublicKey pub = newKeyPair.getPublic();
   byte[] b_pub = pub.getEncoded();
   re[0] = b_priv;
   re[1] = b_pub;
   return re;
  }
  return null;
}

/**
  * 新建密鑰對
  * 
  * @return KeyPair對象
  */
public static KeyPair creatmyKey() {
  KeyPair myPair;
  long mySeed;
  mySeed = System.currentTimeMillis();
  try {
   KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
   SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
   random.setSeed(mySeed);
   keyGen.initialize(1024, random);
   myPair = keyGen.generateKeyPair();
  } catch (Exception e1) {
   return null;
  }
  return myPair;
}

/**
  * 使用RSA公鑰加密數據
  * 
  * @param pubKeyInByte
  *            打包的byte[]形式公鑰
  * @param data
  *            要加密的數據
  * @return 加密數據
  */
public static byte[] encryptByRSA(byte[] pubKeyInByte, byte[] data) {
  try {
   KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
   X509EncodedKeySpec pub_spec = new X509EncodedKeySpec(pubKeyInByte);
   PublicKey pubKey = mykeyFactory.generatePublic(pub_spec);
   Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
   cipher.init(Cipher.ENCRYPT_MODE, pubKey);
   return cipher.doFinal(data);
  } catch (Exception e) {
   return null;
  }
}

/**
  * 用RSA私鑰解密
  * 
  * @param privKeyInByte
  *            私鑰打包成byte[]形式
  * @param data
  *            要解密的數據
  * @return 解密數據
  */
public static byte[] decryptByRSA(byte[] privKeyInByte, byte[] data) {
  try {
   PKCS8EncodedKeySpec priv_spec = new PKCS8EncodedKeySpec(
     privKeyInByte);
   KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
   PrivateKey privKey = mykeyFactory.generatePrivate(priv_spec);
   Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
   cipher.init(Cipher.DECRYPT_MODE, privKey);
   return cipher.doFinal(data);
  } catch (Exception e) {
   return null;
  }

}

 

/**
 * 使用RSA私鑰加密數據
 * 
 * @param pubKeyInByte
 *            打包的byte[]形式私鑰
 * @param data
 *            要加密的數據
 * @return 加密數據
 */
public static byte[] encryptByRSA1(byte[] privKeyInByte, byte[] data) {
  try {
    PKCS8EncodedKeySpec priv_spec = new PKCS8EncodedKeySpec(
      privKeyInByte);
    KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
    PrivateKey privKey = mykeyFactory.generatePrivate(priv_spec);
    Cipher cipher = Cipher.getInstance(mykeyFactory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, privKey);
    return cipher.doFinal(data);
   } catch (Exception e) {
    return null;
   }

}

/**
 * 用RSA公鑰解密
 * 
 * @param privKeyInByte
 *            公鑰打包成byte[]形式
 * @param data
 *            要解密的數據
 * @return 解密數據
 */
public static byte[] decryptByRSA1(byte[] pubKeyInByte, byte[] data) {
 try {
   KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
   X509EncodedKeySpec pub_spec = new X509EncodedKeySpec(pubKeyInByte);
   PublicKey pubKey = mykeyFactory.generatePublic(pub_spec);
   Cipher cipher = Cipher.getInstance(mykeyFactory.getAlgorithm());
   cipher.init(Cipher.DECRYPT_MODE, pubKey);
   return cipher.doFinal(data);
  } catch (Exception e) {
   return null;
  }
}


/**
 * 計算字符串的SHA數字摘要,以byte[]形式返回
 */
public static byte[] MdigestSHA(String source) {
 //byte[] nullreturn = { 0 };
 try {
  MessageDigest thisMD = MessageDigest.getInstance("SHA");
  byte[] digest = thisMD.digest(source.getBytes("UTF-8"));
  return digest;
 } catch (Exception e) {
  return null;
 }
}
 /**
   *測試
   * 
   */
 public static void main(String[] args) {
   try {
    //私鑰加密 公鑰解密
    //生成私鑰-公鑰對
    Object[] v = giveRSAKeyPairInByte();
    //獲得摘要
    byte[] source =MdigestSHA("假設這是要加密的客戶數據");
    //使用私鑰對摘要進行加密 獲得密文 即數字簽名
    byte[] sign = sign((byte[]) v[0], source);
    //使用公鑰對密文進行解密,解密後與摘要進行匹配
    boolean yes = verify((byte[]) v[1], source, sign);
    if (yes)
     System.out.println("匹配成功 合法的簽名!");
   


    
   //公鑰加密私鑰解密
    //獲得摘要
    byte[] sourcepub_pri = ("13265986584||316494646546486498||01||public").getBytes("UTF-8");

    //使用公鑰對摘要進行加密 獲得密文
    byte[] signpub_pri =encryptByRSA((byte[]) v[1] ,sourcepub_pri);
    //System.out.println("公鑰加密密文:"+new String(Base64.encodeBase64(signpub_pri)));

    //使用私鑰對密文進行解密 返回解密後的數據
    byte[] newSourcepub_pri=decryptByRSA((byte[]) v[0],signpub_pri);
    
    System.out.println("私鑰解密:"+new String(newSourcepub_pri,"UTF-8"));
    //對比源數據與解密後的數據
    if(Arrays.equals(sourcepub_pri, newSourcepub_pri))
     System.out.println("匹配成功 合法的私鑰!");
    
    
    
    //私鑰加密公鑰解密
    //獲得摘要
    //byte[] sourcepri_pub = MdigestSHA("假設這是要加密的客戶數據");
    byte[] sourcepri_pub = ("13265986584||316494646546486498||01||private").getBytes("UTF-8");

    
    //使用私鑰對摘要進行加密 獲得密文
    byte[] signpri_pub =encryptByRSA1((byte[]) v[0] ,sourcepri_pub);
    
 //   System.out.println("私鑰加密密文:"+new String(Base64.encodeBase64(sign11)));
    //使用公鑰對密文進行解密 返回解密後的數據
    byte[] newSourcepri_pub=decryptByRSA1((byte[]) v[1],signpri_pub);
    
    System.out.println("公鑰解密:"+new String(newSourcepri_pub,"UTF-8"));

   

    
    String PUBLICKEY="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCEGENnf3rdiO20isoLQqezw12FoWXII9FBw8nR1MWQ3X0CVzOsqY1hOmxD/YI9OB7WVIaVax5tj1l+wk6A0v85Z4OpGWqz4B5L3fCUlBwf/M6DXHlSN1OZttvQF3OeWvc6gvJHihR7pp18zc4KfCJx0Ry6IrGH/2SNOVE1AIgvRQIDAQAB";
    String PRIVATEKEY="MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIQYQ2d/et2I7bSKygtCp7PDXYWhZcgj0UHDydHUxZDdfQJXM6ypjWE6bEP9gj04HtZUhpVrHm2PWX7CToDS/zlng6kZarPgHkvd8JSUHB/8zoNceVI3U5m229AXc55a9zqC8keKFHumnXzNzgp8InHRHLoisYf/ZI05UTUAiC9FAgMBAAECgYAGNcHNds/G5G4QY8n1149cwx19b8YCL7Thu5ucUr1q/w6mcoUKY/oyjPWUCLH7wMyqVNTy51NJ4UhazjW0lrbK4ZbPDHFij9CiZ7QFASiQ/TQWaL+KSIWnE6/rK9IdouwFKxk+cvvLteZoAXP6mFcrsa7LzfkENiIMu7mjpTNHAQJBANXv9U5JWOAVhWHDQcEWKn7YKpAVRleXdeUeJrXcdkqBDI+P6suA9j+ahDREfu+x65wUsrJotPHUXgJG0TarJIUCQQCeEPLrv6Qvi5+nbn2Eifn/fjsmIdI0U2WZKDHWJEnLsRUuGDNYxVE/SPDNDedA2OHeFB6j0Kk/ECdsWnUq6zvBAkAgUGViFMwa1MVX1fFZo+p5TFdpef0s/9Cr8djxAULQ0BtAmAFkCa+oPcOYTXxK4jnvUmUHc69ZE7W7bEzvj/wtAkB50X4mClAzBFxK4XCC0QOG0HYtcStbgFpwqvWdn+Hvxc4Y9DW+WHPBXimXHvv2ki+gw8jJX2rQW1bGvwBFz30BAkASPkORJxVWv91StjI2f/HXDO5eG5/su/XIb3eajaLUSEdaQlcs3ywLrrJ0o3VAR0J9aq59cmp6em017AMnmbF7";
  
    byte[] signPrivate=Base64.decodeBase64(PRIVATEKEY.getBytes());
    byte[] signPublic=Base64.decodeBase64(PUBLICKEY.getBytes());
   

    String publicpwd ="N/b4nYbbLFVq0yTAIOpNNydtNQUCQxQy0B7bD6kzxLMW2guYxXtWOC/9Z5dpWecx/y7d5CezUJ6cf/8++msiNie4DcKBaFDFPh5rPbjeEB+DRfhjcdR2BsVGXWLsq3dLYLgZObQXG6Tb9rXakuH34Y+6KIIwCjiODH2QAU+PSiM=";
    String privatepwd ="MTMyNjU5ODY1ODR8fDMxNjQ5NDY0NjU0NjQ4NjQ5OHx8MDF8fHByaXZhdGU=";
    //使用私鑰對密文進行解密 返回解密後的數據
    byte[] newSource111=decryptByRSA(signPrivate,Base64.decodeBase64(publicpwd.getBytes()));
    System.out.println("私鑰解密1:"+new String(newSource111,"UTF-8"));
    
    
    
    
    
    
       
   } catch (Exception e) {
    e.printStackTrace();
   }
  

 
 }

}


 運行結果:

匹配成功 合法的簽名!
私鑰解密:13265986584||316494646546486498||01||public
匹配成功 合法的私鑰!
公鑰解密:13265986584||316494646546486498||01||private
私鑰解密1:13265986584||316494646546486498||01||3156464564
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章