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[32]
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 17983 days, 23 hours, 37 minutes ago.