熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

JAVA裡面RSA加密算法的使用

2022-06-13   來源: Java核心技術 

  打算寫這個類用於spark插件加密對話消息用

  RSA的Java實現不能一次加密很大的字符自己處理了一下見下面的代碼

  Base編碼類用的是一個Public domain Base for java

  其他的保存公鑰到文件等簡單的實現就不詳細說了看代碼吧

  ==============================================

  import javasecurity*;

  import javasecurityspecPKCSEncodedKeySpec;

  import javasecurityspecXEncodedKeySpec;

  import javautilHashMap;

  import javautilMap;

  import javaxcrypto*;

  import javaio*;

  public class Encryptor {

  private static final String KEY_FILENAME = c:\\mykeydat;

  private static final String OTHERS_KEY_FILENAME = c:\\Otherskeydat;

  // private static final int KEY_SIZE = ;

  // private static final int BLOCK_SIZE = ;

  // private static final int OUTPUT_BLOCK_SIZE = ;

  private static final int KEY_SIZE = ; //RSA key 是多少位的

  private static final int BLOCK_SIZE = ;    //一次RSA加密操作所允許的最大長度

  //這個值與 KEY_SIZE 已經padding方法有關因為 的key的輸出是key輸出是字節

  //可能個字節用於保存padding信息了所以最多可用的就只有字節了

  private static final int OUTPUT_BLOCK_SIZE = ;

  private SecureRandom secrand;

  private Cipher rsaCipher;

  private KeyPair keys;

  private Map<String Key> allUserKeys;

  public Encryptor() throws Exception {

  try {

  allUserKeys = new HashMap<String Key>();

  secrand = new SecureRandom();

  //SunJCE Provider 中只支持ECB mode試了一下只有PKCSPADDING可以直接還原原始數據

  //NOPadding導致解壓出來的都是blocksize長度的數據還要自己處理

  //參見 l

  //

  //另外根據 OpenJDKbsrc(l)

  // 中代碼的注釋使用RSA來加密大量數據不是一種標准的用法所以現有實現一次doFinal調用之進行一個RSA操作

  //如果用doFinal來加密超過的一個操作所允許的長度數據將拋出異常

  //根據keysize的長度典型的個長度的key和PKCSPADDING一起使用時

  //一次doFinal調用只能加密個byte的數據(NOPadding 和 keysize時個字節長度)

  //(長度的key和PKCSPADDING 最多允許字節一次)

  //想用來加密大量數據的只能自己用其他辦法實現了可能RSA加密速度比較慢吧要用AES才行

  rsaCipher = CiphergetInstance(RSA/ECB/PKCSPADDING);

  } catch (NoSuchAlgorithmException e) {

  eprintStackTrace();

  } catch (NoSuchPaddingException e) {

  eprintStackTrace();

  throw e;

  }

  ObjectInputStream in;

  try {

  in = new ObjectInputStream(new FileInputStream(KEY_FILENAME));

  } catch (FileNotFoundException e) {

  if (false == GenerateKeys())

  {

  throw e;

  }

  LoadKeys();

  return;

  }

  keys = (KeyPair) inreadObject();

  inclose();

  LoadKeys();

  }

  /*

  * 生成自己的公鑰和私鑰

  */

  private Boolean GenerateKeys() {

  try {

  KeyPairGenerator keygen = KeyPairGeneratorgetInstance(RSA);

  // secrand = new SecureRandom();

  // sedSeed之後會造成 生成的密鑰都是一樣的

  // secrandsetSeed(chatencrptorgetBytes()); // 初始化隨機產生器

  //key長度至少長度不過好像說現在用才算比較安全的了

  keygeninitialize(KEY_SIZE secrand); // 初始化密鑰生成器

  keys = keygengenerateKeyPair(); // 生成密鑰組

  AddKey(me EncodeKey(keysgetPublic()));

  } catch (NoSuchAlgorithmException e) {

  eprintStackTrace();

  return false;

  }

  ObjectOutputStream out;

  try {

  out = new ObjectOutputStream(new FileOutputStream(KEY_FILENAME));

  } catch (IOException e) {

  eprintStackTrace();

  return false;

  }

  try {

  outwriteObject(keys);

  } catch (IOException e) {

  eprintStackTrace();

  return false;

  } finally {

  try {

  outclose();

  } catch (IOException e) {

  eprintStackTrace();

  return false;

  }

  }

  return true;

  }

  public String EncryptMessage(String toUser String Message) throws IOException {

  Key pubkey = allUserKeysget(toUser);

  if ( pubkey == null )

  {

  throw new IOException(NoKeyForThisUser) ;

  }

  try {

  //PublicKey pubkey = keysgetPublic();

  rsaCipherinit(CipherENCRYPT_MODE pubkey secrand);

  //Systemoutprintln(rsaCiphergetBlockSize()); 返回非block 加密算法來的?

  //Systemoutprintln(MessagegetBytes(utf)length);

  //byte[] encryptedData = rsaCipherdoFinal(MessagegetBytes(utf));

  byte[] data = MessagegetBytes(utf);

  int blocks = datalength / BLOCK_SIZE ;

  int lastBlockSize = datalength % BLOCK_SIZE ;

  byte [] encryptedData = new byte[ (lastBlockSize == ? blocks : blocks + )* OUTPUT_BLOCK_SIZE];

  for (int i=; i < blocks; i++)

  {

  //int thisBlockSize = ( i + ) * BLOCK_SIZE > datalength ? datalength i * BLOCK_SIZE : BLOCK_SIZE ;

  rsaCipherdoFinal(datai * BLOCK_SIZE BLOCK_SIZE encryptedData i * OUTPUT_BLOCK_SIZE);

  }

  if (lastBlockSize != ){

  rsaCipherdoFinal(data blocks * BLOCK_SIZE lastBlockSizeencryptedData blocks * OUTPUT_BLOCK_SIZE);

  }

  //Systemoutprintln(encryptedlength); 如果要機密的數據不足/字節加密後補全成為變為長度的

  //數量比較小時BaseGZIP產生的長度更長沒什麼優勢

  //Systemoutprintln(BaseencodeBytes(encryptedBaseGZIP)length());

  //Systemoutprintln(BaseencodeBytes(encrypted)length());

  //Systemoutprintln (rsaCiphergetOutputSize());

  //這個getOutputSize 只對 輸入小於最大的block時才能得到正確的結果其實就是補全 數據為/ 字節

  return BaseencodeBytes(encryptedData);

  } catch (InvalidKeyException e) {

  eprintStackTrace();

  throw new IOException(InvalidKey) ;

  }catch (ShortBufferException e) {

  eprintStackTrace();

  throw new IOException(ShortBuffer) ;

  }

  catch (UnsupportedEncodingException e) {

  eprintStackTrace();

  throw new IOException(UnsupportedEncoding) ;

  } catch (IllegalBlockSizeException e) {

  eprintStackTrace();

  throw new IOException(IllegalBlockSize) ;

  } catch (BadPaddingException e) {

  eprintStackTrace();

  throw new IOException(BadPadding) ;

  }finally {

  //catch 中 return 或者throw之前都會先調用一下這裡

  }

  }

  public String DecryptMessage(String Message) throws IOException {

  byte[] decoded = Basedecode(Message);

  PrivateKey prikey = keysgetPrivate();

  try {

  rsaCipherinit(CipherDECRYPT_MODE prikey secrand);

  int blocks = decodedlength / OUTPUT_BLOCK_SIZE;

  ByteArrayOutputStream decodedStream = new ByteArrayOutputStream(decodedlength);

  for (int i = ;i < blocks ; i ++ )

  {

  decodedStreamwrite (rsaCipherdoFinal(decodedi * OUTPUT_BLOCK_SIZE OUTPUT_BLOCK_SIZE));

  }

  return new String(decodedStreamtoByteArray() UTF);

  } catch (InvalidKeyException e) {

  eprintStackTrace();

  throw new IOException(InvalidKey);

  } catch (UnsupportedEncodingException e) {

  eprintStackTrace();

  throw new IOException(UnsupportedEncoding);

  } catch (IllegalBlockSizeException e) {

  eprintStackTrace();

  throw new IOException(IllegalBlockSize);

  } catch (BadPaddingException e) {

  eprintStackTrace();

  throw new IOException(BadPadding);

  } finally {

  // catch 中 return 或者throw之前都會先調用一下這裡

  }

  }

  public boolean AddKey(String user String key) {

  PublicKey publickey;

  try {

  publickey = DecodePublicKey(key);

  } catch (Exception e) {

  return false;

  }

  allUserKeysput(user publickey);

  SaveKeys();

  return true;

  }

  private boolean LoadKeys() {

  BufferedReader input;

  try {

  input = new BufferedReader(new InputStreamReader(

  new FileInputStream(OTHERS_KEY_FILENAME)));

  } catch (FileNotFoundException e) {

  // eprintStackTrace();

  return false;

  }

  try {

  allUserKeysclear();

  String line;

  while ((line = inputreadLine()) != null) {

  String[] temp = linesplit(\\|);

  String user = temp[];

  PublicKey key = DecodePublicKey(temp[]);

  allUserKeysput(user key);

  }

  } catch (Exception e) {

  return false;

  } finally {

  try {

  inputclose();

  } catch (Exception e) {

  return false;

  }

  }

  return true;

  }

  private boolean SaveKeys() {

  FileWriter output;

  try {

  output = new FileWriter(OTHERS_KEY_FILENAME);

  } catch (IOException e) {

  // printStackTrace();

  return false;

  }

  try {

  for (String user : allUserKeyskeySet()) {

  Key key = allUserKeysget(user);

  outputwrite(user + | + EncodeKey(key) + \n);

  }

  } catch (IOException e) {

  // printStackTrace();

  return false;

  } finally {

  try {

  outputclose();

  } catch (Exception e) {

  return false;

  }

  }

  return true;

  }

  /**

  * 解密base編碼得到公鑰

  *

  * @param key

  *            密鑰字符串(經過base編碼)

  * @throws Exception

  */

  public static PublicKey DecodePublicKey(String key) throws Exception {

  byte[] keyBytes;

  keyBytes = Basedecode(key);

  XEncodedKeySpec keySpec = new XEncodedKeySpec(keyBytes);

  KeyFactory keyFactory = KeyFactorygetInstance(RSA);

  PublicKey publicKey = keyFactorygeneratePublic(keySpec);

  return publicKey;

  }

  /**

  * 解密base編碼得到私鑰

  *

  * @param key

  *            密鑰字符串(經過base編碼)

  * @throws Exception

  */

  public static PrivateKey DecodePrivateKey(String key) throws Exception {

  byte[] keyBytes;

  keyBytes = Basedecode(key);

  PKCSEncodedKeySpec keySpec = new PKCSEncodedKeySpec(keyBytes);

  KeyFactory keyFactory = KeyFactorygetInstance(RSA);

  PrivateKey privateKey = keyFactorygeneratePrivate(keySpec);

  return privateKey;

  }

  /**

  * 編碼key為base字符串

  *

  * @return

  */

  public static String EncodeKey(Key key) {

  byte[] keyBytes = keygetEncoded();

  // Systemoutprint(keygetFormat()) ;

  String s = BaseencodeBytes(keyBytes);

  return s;

  }

  }

  ===============測試類============================

  import javautilIterator ;

  import javasecuritySecurity ;

  import javasecurityProvider ;

  public class Test {

  /**

  * @param args

  */

  public static void main(String[] args) {

  //   Provider [ ] providers = SecuritygetProviders () ;

  //   for ( int i = ; i < providerslength ; i++ )

  //   {

  //   String name = providers[i]getName () ;

  //   String info = providers[i]getInfo () ;

  //   double version = providers[i]getVersion () ;

  //   Systemoutprintln ( ) ;

  //   Systemoutprintln ( name: + name ) ;

  //   Systemoutprintln ( info: + info ) ;

  //   Systemoutprintln ( version: + version ) ;

  //

  //   for ( Iterator iter = providers[i]keySet(erator () ; iterhasNext () ; )

  //   {

  //   String key = (String) iternext () ;

  //   Systemoutprintln ( \t + key +

  //   \t +

  //   providers[i]getProperty ( key ) ) ;

  //   }

  //

  //   Systemoutprintln (

  //

  //   );

  //   }

  //

  //   int i = / ;

  //   Systemoutprintln(i);

  //   i = / ;

  //   Systemoutprintln(i);

  //   i = / ;

  //   Systemoutprintln(i);

  //   i = / ;

  //   Systemoutprintln(i);

  //String str = widebriht的測試哈哈^_^;

  //String str = MIIBIjANBgkqhkiGwBAQEFAAOCAQAMIIBCgKCAQEAdYTvxxgsuSmgqJzPWzSOziMDnOV+tAxQGumNAJKcBxOlDhQlqTGRnUoqIpzbrioFJBtMswAeA+pfpJhFyqodIfrrIYPUgwRlLozGAhuCBOADQNKEgUgOTQ/joEYoYPCHKx/vYQncOeaxOCqcXBWViwWgPrgqjCarQLMedUNMCYcXZGvqIyJsFjuLsNaKkyfjIqquFzhjvIEDCtrMNyTvVcoVrDGTECKfJftoeCTXrhcgzMBdaGDXFQezQIepMdPAT+kga/qJbILMwyCDhwPmHUNQAmdMpJbZTTwIDAQAB;

  String str = MIIBIjANBgkqhkiGwBMIIBIjANBgkqhkiGwBMIIBIjANBgkqhkiGwBMIIBIjANBgkqhkiGwBMIIBIjANBgkqhkiGwBMIIBIjANBgkqhkiGwBMIIBIjANBgkqhkiGwBMIIBIjANBgkqhkiGwBMIIBIjANBgkqhkiGwBMIIBIjANBgkqhkiGwBMIIBIjANBgkqhkiGwBMIIBIjANBgkqhkiGwBddddd;

  try {

  Encryptor ddd = new Encryptor();

  str = dddEncryptMessage(me str);

  // Systemoutprintln(strlength());

  String str = jhahahh my god ;

  str = dddEncryptMessage(me str);

  str = dddDecryptMessage(str);

  str = dddDecryptMessage(str);

  } catch (Exception e) {

  if (egetMessage() == NoKeyForThisUser) {

  Systemoutprintln(NoKeyForThisUser);

  }

  }

  // str = dddDecryptMessage(

  // inIyPfFXtoNWXuYLBbTkIaaxZFzgWuMfYTqpTbUUQNTiKlXnS+WShC/ZGLnoXvOsDmiJ+zI/WTgvOOWXE+G+edGzhbfRGPxhGMJply/FsIErsKgZmybEREFIP/bxGmrZhyj/NwZlnqUg=);

  //Systemoutprintln(str);

  }

  }


From:http://tw.wingwit.com/Article/program/Java/hx/201311/25887.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.