IAIK JCE in Jython

… cause cryptographic algorithm's extensibility is important

Lukas Prokop, pygraz, Nov 2014

Jython?

  • python on the JVM
  • Primary target is a complete implementation of python (CPython compatibility)
  • python 2.6 is stable. python 2.7 in second beta
  • python → Java byte code → JVM execution

Jython!

  • jython.org
  • Actual multithreading; no GIL!
  • python3? We are not there yet
  • jython as a simple jar file

Example command line

java -cp "iaik_jce_full.jar:jython-standalone-2.7-b2.jar" \
  org.python.util.jython file.py

Cryptography in Java

Java Duke

Accelerating cryptography

  • MD5 got broken (2004–2013).
  • RSA-768 [768 bit keylength] was the latest RSA record (2009).
  • Erich Wenger and Paul Wolfger of IAIK recently solved the discrete logarithm problem on a 113-bit Koblitz curve (May 2014).

If a vulnerability is published, exploits occur fast.

Considerations

Are your crypto algorithms implemented properly?

Who fixes published vulnerabilities in your software stack? How fast?

Whom do you trust not to screw up?

Do you trust Sun?

Do you trust the Python Software Foundation?

Let's make algorithms exchangable!

A developer's usecases

  • Generate keys (PRNGs, public/private keys, …)
  • Encrypt data
  • Decrypt data
  • Hash & Sign data
  • Verify data
  1. Get an instance of your cryptosystem
  2. Use an uniform interface for your operation(s)

Crypto software vendors

Java (JCA):

  • Sun
  • Bouncy Castle
  • IAIK JCE

Crypto software vendors

Python:

Python Software Foundationhashlib
Dwayne C. Litzenberger, et alpycrypto
several volunteerscryptography
[NaCl:] djb, Tanja Lange, Peter Schwabepynacl

[Security, Security::Cryptography] matches 333 packages
(as of Aug 2014)

Here: IAIK-JCE

IAIK JCE

jce.iaik.tugraz.at

Here: IAIK-JCE

IAIK JCE at Wikipedia

It even has a Wikipedia article 😀

Hash a file (with hashlib)

import hashlib

s = hashlib.sha1()
with open('filetohash') as fp:
    s.update(fp.read())

print(s.hexdigest())
# prints eg. c4f8cca53c9c0734489b9640eee2fdcd52fd80fe

Hash a file (with sha1sum)

$ sha1sum filetohash
c4f8cca53c9c0734489b9640eee2fdcd52fd80fe  filetohash

Hash a file (with IAIK-JCE)

import iaik.security.provider.IAIK
from java.security import MessageDigest

iaik.security.provider.IAIK.addAsProvider()

filepath = 'filetohash'
d = MessageDigest.getInstance("SHA-1")

with open(filepath, 'rb') as fp:
    d.update(fp.read())

hexrepr = ['{:02x}'.format(b % 256) for b in d.digest()]
print(''.join(hexrepr))

List providers

import java.security.Provider
from java.security import Security
import iaik.security.provider.IAIK

iaik.security.provider.IAIK.addAsProvider()

for provider in Security.getProviders():
    print("Name         : {}".format(provider.getName()))
    print("Information  : {}".format(provider.getInfo()))
    print("Version      : {}\n".format(provider.getVersion()))
…
Name         : IAIK
Information  : IAIK Security Provider v5.2, evaluation version
Version      : 5.2

Name         : SUN
Information  : SUN (DSA key/parameter generation; DSA signing; SHA-1, MD5 digests; SecureRandom; X.509 certificates; JKS keystore; PKIX CertPathValidator; PKIX CertPathBuilder; LDAP, Collection CertStores, JavaPolicy Policy; JavaLoginConfig Configuration)
Version      : 1.7

Name         : SunRsaSign
Information  : Sun RSA signature provider
Version      : 1.7

Name         : SunJSSE
Information  : Sun JSSE provider(PKCS12, SunX509 key/trust factories, SSLv3, TLSv1)
Version      : 1.7

Name         : SunJCE
Information  : SunJCE Provider (implements RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, Diffie-Hellman, HMAC)
Version      : 1.7

Name         : SunJGSS
Information  : Sun (Kerberos v5, SPNEGO)
Version      : 1.7

…

List algorithms

See standard names list

import java.security.Provider
from java.security import Security
import iaik.security.provider.IAIK

iaik.security.provider.IAIK.addAsProvider()

prov = iaik.security.provider.IAIK()

for service in prov.getServices():
    print('Algorithm      : {}'.format(service))
…
Algorithm      : IAIK: SecureRandom.SHA1PRNG -> iaik.security.random.SecRandomSpi$SHA1RandomSpi

Algorithm      : IAIK: SecureRandom.SHA384PRNG -> iaik.security.random.SecRandomSpi$SHA384RandomSpi

Algorithm      : IAIK: SecureRandom.SHA512PRNG -> iaik.security.random.SecRandomSpi$SHA512RandomSpi
…
Algorithm      : IAIK: MessageDigest.KECCAK224 -> iaik.security.md.KECCAK224
  aliases: [KECCAK-224]

Algorithm      : IAIK: MessageDigest.KECCAK256 -> iaik.security.md.KECCAK256
  aliases: [KECCAK-256]

Algorithm      : IAIK: MessageDigest.KECCAK384 -> iaik.security.md.KECCAK384
  aliases: [KECCAK-384]

Algorithm      : IAIK: MessageDigest.KECCAK512 -> iaik.security.md.KECCAK512
  aliases: [KECCAK-512]
…
Algorithm      : IAIK: KeyPairGenerator.DH -> iaik.security.dh.DHKeyPairGenerator
  aliases: [DiffieHellman, Diffie-Hellman, 1.2.840.113549.1.3.1]
…
Algorithm      : IAIK: SecretKeyFactory.RC6 -> iaik.security.cipher.GeneralKeyFactory
…
  

Hashing a password

Visit to Importland

import java.security.Provider
import iaik.security.provider.IAIK

import java.security.SecureRandom as SecureRandom
import java.security.spec.KeySpec as KeySpec

import javax.crypto.SecretKey as SecretKey
import javax.crypto.SecretKeyFactory as SecretKeyFactory
import javax.crypto.spec.PBEKeySpec as PBEKeySpec
import javax.crypto.spec.SecretKeySpec as SecretKeySpec

import jarray
import sys

Generating salt

# making SHA512PRNG available
iaik.security.provider.IAIK.addAsProvider()

def generateSalt():
    # SecureRandom might take very long reading from /dev/random
    salt = jarray.zeros(20, "b")
    rand = SecureRandom.getInstance("SHA512PRNG")
    rand.nextBytes(salt)
    return salt

Hashing

def hashPassword(pwd, salt):
    pbkdf2 = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
    spec = PBEKeySpec(pwd, salt, 65536, 128)
    presecret = pbkdf2.generateSecret(spec)
    secret = SecretKeySpec(presecret.getEncoded(), "AES")
    return secret.getEncoded()

Using the interface

if __name__ == "__main__":
    salt = generateSalt()
    pwd = hashPassword("MyVerySecr!tP4ssworD", salt)
    # store {salt, pwd} in database

    userlogin = "MyVerySecr!tP4ssworD"
    pwd2 = hashPassword(userlogin, salt)
    # verification

    if pwd == pwd2:
        print("User has been authenticated")
    else:
        print("User login failed")
        sys.exit(1)

😊 Thanks!