Ruby openssl


#1

Hi,

Whats the ruby equivalent code for the following decryption code which
is
written in java.

1.7 Decrypt Token
To be completed.
1.7.1 Sample Java Code

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

public class TokenDecrypter {
public static final String UTF8_ENC = “UTF-8”;
public byte [] hmacKey = null;
public byte [] cipherKey = null;

// derive the hmac Key and the CipherKey with initialization using the
Cert Id

public TokenDecrypter (String certId) throws NoSuchAlgorithmException
{

MessageDigest md = MessageDigest.getInstance("SHA1");
byte [] masterKey = certId.getBytes();
byte [] baseHmac = new byte[masterKey.length +1];
baseHmac[0] = 1; //Use 1 for first bit in the key
System.arraycopy(masterKey, 0, baseHmac, 1, masterKey.length);
md.update(baseHmac);
hmacKey = md.digest();


byte [] baseCipher = new byte[masterKey.length +1];
baseCipher[0] = 0; //Use 0 for first bit in the key
System.arraycopy(masterKey, 0, baseCipher, 1, masterKey.length);
md.update(baseCipher);
byte [] hash = md.digest();

cipherKey = new byte[16]; //16byte = 128 bit encryption is used
    System.arraycopy(hash, 0, cipherKey, 0,16);

}

public String decrypt(String cipherTxt) throws
GeneralSecurityException, UnsupportedEncodingException {

Mac hmacObj = Mac.getInstance("HMACSHA1");

// first Base64 Decode
byte[] bin = Base64.decodeBase64(cipherTxt.getBytes());

//seperate  the hmac from the cipher
byte [] hmacReceived = new byte[20];
System.arraycopy(bin, bin.length-20, hmacReceived, 0, 20);


//seperate  the cipher from the hmac
byte [] cipherBytes = new byte[bin.length-20];
System.arraycopy(bin, 0, cipherBytes, 0, cipherBytes.length);


// Hmac Verification Part
  Key hmacKey = new SecretKeySpec(this.hmacKey, "HMACSHA1");
  hmacObj.init(hmacKey);
  hmacObj.update(cipherBytes);
  byte actual[] = hmacObj.doFinal();

  if (actual.length != hmacReceived.length)
    throw new GeneralSecurityException("Integrity of the message

could not be verified");

  for (int i=0; i < actual.length; i++) {
      if (actual[i] != hmacReceived[i]) {
        throw new GeneralSecurityException("HMAC verification

failure");
}
}

  // Perform AES Decryption

  byte iv[] = new byte[16]; //CIPHER_BLOCK_SIZE
  System.arraycopy(cipherBytes, 0, iv, 0, iv.length);
  SecretKeySpec   key = new SecretKeySpec(this.cipherKey, "AES");
        Cipher  cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
  IvParameterSpec ivSpec = new IvParameterSpec(iv);
  cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
  byte[] decrypted = cipher.doFinal(cipherBytes, 16 ,

cipherBytes.length-16); //discount the 16 byte IV

return new String(decrypted, UTF8_ENC).toString();

}

public Map<String, String> unwrap(String cypherText) throws
GeneralSecurityException, UnsupportedEncodingException {
String decryptedText = decrypt(cypherText);
Map<String, String> keyValuePairs = getKeyValuePairs(decryptedText);
return keyValuePairs;
}

public Map<String, String> getKeyValuePairs(String decryptedText)
throws UnsupportedEncodingException {
Map<String, String> keyValuePairs = new HashMap<String, String>();

String[] items = decryptedText.split("[&=]");

for (int i = 0; i < items.length;) {
  String key = URLDecoder.decode(items[i++], UTF8_ENC);
  String value = URLDecoder.decode(items[i++], UTF8_ENC);
  keyValuePairs.put(key, value);
}

return keyValuePairs;

}

public static void main(String[] str) throws Exception {
String myCertId = “xxxxxxx”;
TokenDecrypter tokenDecrypter = new TokenDecrypter(myCertId);
String token = null;//request.getParameter(“st”); //Or tokenValue
from EPI request

Map<String, String> keyValuePairs = tokenDecrypter.unwrap(token);

String userName = keyValuePairs.get("un");
String authToken = keyValuePairs.get("at");
String eiasToken = keyValuePairs.get("es");

}
}


#2

http://www.catb.org/~esr/faqs/smart-questions.html

Don’t post homework (or worse, commercial work) problems, because we
won’t do them for you.

The documentation for ruby openssl can be found by typing “ruby openssl”
into Google (it’s the first hit)

Example code can be found in the ruby distribution tarball in the
sample/openssl directory, or at
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/sample/openssl/
on the web.

The Ruby openssl code is just a very thin wrapper around the openssl
library, so openssl’s C API documentation will tell you everything you
need to know.

Then start writing code. Then when you have a specific problem, come
back here. Narrow down the problem until you find a few lines of your
Java code which produce a different result to the Ruby code you have
written.

Adding debugging output to show that the conditions are the same in both
pieces of code before this snippet runs, but different after it
runs. Then if you can’t work out why one behaves differently to the
other, post the two pieces of code here together with the start and end
debugging output.