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 20145 days, 7 hours, 29 minutes ago.