Download or view cryptoAES256.frink in plain text format
// Sample encryption and decryption in Frink using Java's cryptographic
// libraries.
//
// This is based on this posting:
//
// http://stackoverflow.com/questions/992019/java-256-bit-aes-password-based-encryption
//
// Also, to turn this into an AEAD algorithm like AES-GCM, see maybe:
// https://javainterviewpoint.com/java-aes-256-gcm-encryption-and-decryption/
//
// By the way, if you want to do AES-256 encryption, you need to enable
// stronger encryption by downloading a policy file for Java. (Crypto
// strength is limited by default due to export restrictions. 128-bit
// encryption may work out of the box. If you get an error that says
// something about "Illegal key length", then you probably don't have the
// unlimited cryptography policy file installed.
//
// You can download it from here:
// http://tinyurl.com/355cx3m
// And go to the bottom of the page and download "Java Cryptography
// Extension (JCE) Unlimited Strength Jurisdiction Policy Files". Inside
// that zip file there are instructions for installing them to the right
// place.
// (On Fedora with OpenJDK, it was /usr/java/jdk1.7.0_03/jre/lib/security
// but this path will change with each release. Sigh.)
password = input["Enter password: "]
// You'll need a way to transmit this salt to the receiver. It doesn't need
// to be kept secret, but does protect against dictionary attacks on your
// password.
salt = randomBytes[32]
println["Randomly-generated salt is: "]
for i=salt
print[padLeft[base[i, 16],2,"0"] + " "]
println[]
// Now turn the password into an array of chars.
pwchars = newJavaArray["char",length[password]]
newJava["java.lang.String",password].getChars[0,length[password],pwchars,0]
// Create a Secret Key Factory
factory = callJava["javax.crypto.SecretKeyFactory", "getInstance", ["PBKDF2WithHmacSHA256"]]
// Create the secret key. This performs 256-bit AES. You can change the
// 256 to 128 if you don't have the unlimited strength crypto files.
// The 65536 is the iteration count.
keyspec = newJava["javax.crypto.spec.PBEKeySpec", [pwchars, salt, 65536, 256]]
tmp = factory.generateSecret[keyspec]
secret = newJava["javax.crypto.spec.SecretKeySpec", [tmp.getEncoded[], "AES"]]
// Algorithms like HTTPS exchange the secret key by a process like
// Diffie-Hellman key exchange. Programs like gpg use something like
// public-key RSA encryption to exchange encrypted secret keys, which are then
// used to initialize the AES encryption which is used to encrypt the body of
// the message.
// constructor for AES encryption with proper padding.
cipher=callJava["javax.crypto.Cipher","getInstance", ["AES/CBC/PKCS5Padding"]]
// text to be encrypted
text = "Frink rocks (or whatever you want to encrypt). \u263a"
// Convert the plaintext to an array of bytes using the specified encoding.
plaintextBytes = stringToBytes[text, "UTF-8"]
// Perform encryption
cipher.init[cipher.ENCRYPT_MODE, secret] // set encryption mode (1)
params = cipher.getParameters[]
// Get initialization vector.
ivClass = callJava["java.lang.Class", "forName", ["javax.crypto.spec.IvParameterSpec"]]
iv = params.getParameterSpec[ivClass].getIV[]
ciphertext = cipher.doFinal[plaintextBytes] // Perform the actual encryption
// Returns a Java array of bytes.
// Dump the encrypted text as hex bytes.
println["\nEncrypted text:"]
for i = ciphertext
print[padLeft[base[i, 16],2,"0"]]
println[]
println[]
// Decrypt
ivparam = newJava["javax.crypto.spec.IvParameterSpec", [iv]]
cipher.init[cipher.DECRYPT_MODE, secret, ivparam] // set decryption mode (2), same key
plaintext = cipher.doFinal[ciphertext]
println["Decrypted text:"]
// Create a Unicode string from the bytes and specified encoding.
println[bytesToString[plaintext, "UTF-8"]]
Download or view cryptoAES256.frink in plain text format
This is a program written in the programming language Frink.
For more information, view the Frink
Documentation or see More Sample Frink Programs.
Alan Eliasen was born 20217 days, 15 hours, 51 minutes ago.