cryptoAES256.frink

View or download 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
//
// 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[8]
println["Randomly-generated salt is: "]
for i=salt
   print[padLeft[base[i<0 ? i+256 : 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"

// Coerce the text to a raw Java string so we can call its getBytes method
// with the specified encoding.  This allows us to handle characters above
// ASCII 127.
plaintextBytes = newJava["java.lang.String", text].getBytes["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<0 ? i+256 : i, 16],2,"0"]] // Bytes in Java are signed
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.
// the toString call forces a conversion from the raw Java String object
// to a Frink type.
println[newJava["java.lang.String",[plaintext, "UTF-8"]].toString[]]


View or download 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 17596 days, 22 hours, 2 minutes ago.