Last active
April 10, 2018 02:42
-
-
Save DennisDenuto/aeb96f82f7a6e8e2efa8126256ddfaa3 to your computer and use it in GitHub Desktop.
aes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.uaa.cypto; | |
import org.bouncycastle.crypto.digests.SHA256Digest; | |
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; | |
import org.bouncycastle.crypto.params.KeyParameter; | |
import org.junit.Test; | |
import javax.crypto.Cipher; | |
import javax.crypto.CipherInputStream; | |
import javax.crypto.CipherOutputStream; | |
import javax.crypto.SecretKey; | |
import javax.crypto.spec.GCMParameterSpec; | |
import javax.crypto.spec.SecretKeySpec; | |
import java.io.FileInputStream; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
import java.io.UnsupportedEncodingException; | |
import java.security.GeneralSecurityException; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.SecureRandom; | |
public class EncryptionKeyServiceTest { | |
@Test | |
public void spike() throws GeneralSecurityException, UnsupportedEncodingException { | |
// encrypt("some-password", "/tmp/lol"); | |
decrypt("some-password", "/tmp/lol.enc"); | |
} | |
private static byte[] generateRandomArry(int sizeInBytes) throws NoSuchAlgorithmException { | |
/* generate random salt */ | |
final byte[] salt = new byte[sizeInBytes]; | |
SecureRandom random = SecureRandom.getInstanceStrong(); | |
random.nextBytes(salt); | |
return salt; | |
} | |
private static final int DEFAULT_GCM_AUTHENTICATION_TAG_SIZE_BITS = 128; | |
private static final int DEFAULT_GCM_IV_NONCE_SIZE_BYTES = 12; | |
private static final int DEFAULT_PBKDF2_ITERATIONS = 65536; | |
private static final int DEFAULT_PBKDF2_SALT_SIZE_BYTES = 32; | |
private static final int DEFAULT_AES_KEY_LENGTH_BITS = 256; | |
private static final String DEFAULT_CIPHER = "AES"; | |
private static final String DEFAULT_CIPHERSCHEME = "AES/GCM/NoPadding"; | |
private static final String DEFAULT_PBKDF2_SCHEME = "PBKDF2WithHmacSHA256"; | |
private int gcmAuthenticationTagSizeBits = DEFAULT_GCM_AUTHENTICATION_TAG_SIZE_BITS; | |
private int gcmIvNonceSizeBytes = DEFAULT_GCM_IV_NONCE_SIZE_BYTES; | |
private int pbkdf2Iterations = DEFAULT_PBKDF2_ITERATIONS; | |
private int pbkdf2SaltSizeBytes = DEFAULT_PBKDF2_SALT_SIZE_BYTES; | |
private int aesKeyLengthBits = DEFAULT_AES_KEY_LENGTH_BITS; | |
private String cipher = DEFAULT_CIPHER; | |
private String cipherscheme = DEFAULT_CIPHERSCHEME; | |
private String pbkdf2Scheme = DEFAULT_PBKDF2_SCHEME; | |
public byte[] generateBouncyKey(byte[] salt) throws UnsupportedEncodingException, NoSuchAlgorithmException { | |
PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest()); | |
gen.init("some-password".getBytes("UTF-8"), salt, 4096); | |
return ((KeyParameter) gen.generateDerivedParameters(128)).getKey(); | |
} | |
public byte[] encrypt(String password, String path, String plaintext) throws GeneralSecurityException, IOException { | |
/* Derive the key*/ | |
// SecretKeyFactory factory = SecretKeyFactory.getInstance(pbkdf2Scheme); | |
// byte[] newSalt = generateRandomArry(pbkdf2SaltSizeBytes); | |
// KeySpec keyspec = new PBEKeySpec(password.toCharArray(), newSalt, pbkdf2Iterations, aesKeyLengthBits); | |
// SecretKey tmp = factory.generateSecret(keyspec); | |
// SecretKey key = new SecretKeySpec(tmp.getEncoded(), cipher); | |
byte[] newSalt = generateRandomArry(pbkdf2SaltSizeBytes); | |
newSalt = Strings.repeat("a", pbkdf2SaltSizeBytes).getBytes(); | |
SecretKey key = new SecretKeySpec(generateBouncyKey(newSalt), cipher); | |
Cipher myCipher = Cipher.getInstance(cipherscheme); | |
byte[] newNonce = generateRandomArry(gcmIvNonceSizeBytes); | |
newNonce = Strings.repeat("b", gcmIvNonceSizeBytes).getBytes(); | |
GCMParameterSpec spec = new GCMParameterSpec(gcmAuthenticationTagSizeBits, newNonce); | |
myCipher.init(Cipher.ENCRYPT_MODE, key, spec); | |
try ( | |
ByteArrayInputStream fileInputStream = new ByteArrayInputStream(plaintext.getBytes()); | |
ByteArrayOutputStream fileOutputStream = new ByteArrayOutputStream(); | |
CipherOutputStream encryptedOutputStream = new CipherOutputStream(fileOutputStream, myCipher); | |
) { | |
// write IV/nonce | |
fileOutputStream.write(newNonce); | |
// write salt | |
fileOutputStream.write(newSalt); | |
byte[] buffer = new byte[32]; | |
while (fileInputStream.read(buffer) > 0) { | |
encryptedOutputStream.write(buffer); | |
} | |
encryptedOutputStream.flush(); | |
encryptedOutputStream.close(); | |
return fileOutputStream.toByteArray(); | |
} catch (IOException e) { | |
throw new SecurityException(e.getMessage(), e); | |
} | |
// return Files.readAllBytes(Paths.get(path + ".enc")); | |
} | |
public byte[] decrypt(String password, String path, byte[] encrypt) throws GeneralSecurityException, UnsupportedEncodingException { | |
// Read configuration from file | |
byte[] myNonce = new byte[gcmIvNonceSizeBytes]; | |
byte[] mySalt = new byte[pbkdf2SaltSizeBytes]; | |
try ( | |
ByteArrayInputStream fileInputStream = new ByteArrayInputStream(encrypt); | |
) { | |
int countReadBytesNonce = fileInputStream.read(myNonce); | |
int countReadBytesSalt = fileInputStream.read(mySalt); | |
} catch (IOException e) { | |
throw new SecurityException(e.getMessage(), e); | |
} | |
System.out.println(String.format("|||%s|||", new String(mySalt))); | |
System.out.println(String.format("|||%s|||", new String(myNonce))); | |
/* Derive the key*/ | |
// SecretKeyFactory factory = SecretKeyFactory.getInstance(pbkdf2Scheme); | |
// KeySpec keyspec = new PBEKeySpec(password.toCharArray(), mySalt, pbkdf2Iterations, aesKeyLengthBits); | |
// SecretKey tmp = factory.generateSecret(keyspec); | |
// SecretKey key = new SecretKeySpec(tmp.getEncoded(), cipher); | |
SecretKey key = new SecretKeySpec(generateBouncyKey(mySalt), cipher); | |
Cipher myCipher = Cipher.getInstance(cipherscheme); | |
GCMParameterSpec spec = new GCMParameterSpec(gcmAuthenticationTagSizeBits, myNonce); | |
myCipher.init(Cipher.DECRYPT_MODE, key, spec); | |
try ( | |
ByteArrayOutputStream fileOutputStream = new ByteArrayOutputStream(); | |
ByteArrayInputStream fileInputStream1 = new ByteArrayInputStream(encrypt); | |
CipherInputStream cipherInputStream = new CipherInputStream(fileInputStream1, myCipher); | |
) { | |
// offset the stream by the bytes already read previosly | |
byte[] skipped = new byte[gcmIvNonceSizeBytes + pbkdf2SaltSizeBytes]; | |
int read = fileInputStream1.read(skipped); | |
// cipherInputStream.skip(gcmIvNonceSizeBytes + pbkdf2SaltSizeBytes); | |
byte[] buffer = new byte[32]; | |
while (cipherInputStream.read(buffer) > 0) { | |
fileOutputStream.write(buffer); | |
} | |
return fileOutputStream.toByteArray(); | |
} catch (IOException e) { | |
throw new SecurityException(e.getMessage(), e); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment