Java Tutorial/Security/Password Based Encryption

Материал из Java эксперт
Перейти к: навигация, поиск

PBE File Encrypt

import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public class MainClass  {
  public static void main(String[] args) throws Exception{
    Cipher cipher = createCipher(Cipher.ENCRYPT_MODE);
    applyCipher("file_to_encrypt", "encrypted_file", cipher);
    cipher = createCipher(Cipher.DECRYPT_MODE);
    applyCipher("file_to_decrypt", "decrypted_file", cipher);
  }
  static Cipher createCipher(int mode) throws Exception {
    PBEKeySpec keySpec = new PBEKeySpec("test".toCharArray());
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
    SecretKey key = keyFactory.generateSecret(keySpec);
    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update("input".getBytes());
    byte[] digest = md.digest();
    byte[] salt = new byte[8];
    for (int i = 0; i < 8; ++i)
      salt[i] = digest[i];
    PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 20);
    Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
    cipher.init(mode, key, paramSpec);
    return cipher;
  }
  static void applyCipher(String inFile, String outFile, Cipher cipher) throws Exception {
    CipherInputStream in = new CipherInputStream(new FileInputStream(inFile), cipher);
    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outFile));
    int BUFFER_SIZE = 8;
    byte[] buffer = new byte[BUFFER_SIZE];
    int numRead = 0;
    do {
      numRead = in.read(buffer);
      if (numRead > 0)
        out.write(buffer, 0, numRead);
    } while (numRead == 8);
  }
}





PBE With SHA And Two fish

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import sun.misc.BASE64Decoder;
public class MainClass {
  public static void main(String[] args) throws Exception {
    System.out.println(decrypt(new char[] { "a", "b", "c", "d" }, "plaintext1234567890"));
  }
  private static String decrypt(char[] password, String text) throws Exception {
    String salt = text.substring(0, 12);
    String ciphertext = text.substring(12, text.length());
    BASE64Decoder decoder = new BASE64Decoder();
    byte[] saltArray = decoder.decodeBuffer(salt);
    byte[] ciphertextArray = decoder.decodeBuffer(ciphertext);
    PBEKeySpec keySpec = new PBEKeySpec(password);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithSHAAndTwofish-CBC");
    SecretKey key = keyFactory.generateSecret(keySpec);
    PBEParameterSpec paramSpec = new PBEParameterSpec(saltArray, 1000);
    Cipher cipher = Cipher.getInstance("PBEWithSHAAndTwofish-CBC");
    cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
    return new String(cipher.doFinal(ciphertextArray));
  }
}





Read the first 8 bytes of the ciphertext and use that as the salt

import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import sun.misc.BASE64Encoder;
public class MainClass {
  public static void main(String[] args) throws Exception {
   System.out.println(encrypt(new char[] { "a", "b", "c", "d" }, "plaintext1234567890"));
  }
  private static String encrypt(char[] password, String plaintext) throws Exception {
    byte[] salt = new byte[8];
    Random random = new Random();
    random.nextBytes(salt);
    PBEKeySpec keySpec = new PBEKeySpec(password);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithSHAAndTwofish-CBC");
    SecretKey key = keyFactory.generateSecret(keySpec);
    PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 1000);
    Cipher cipher = Cipher.getInstance("PBEWithSHAAndTwofish-CBC");
    cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
    byte[] ciphertext = cipher.doFinal(plaintext.getBytes());
    BASE64Encoder encoder = new BASE64Encoder();
    String saltString = encoder.encode(salt);
    String ciphertextString = encoder.encode(ciphertext);
    return saltString + ciphertextString;
  }

}