Tuesday, April 9, 2013

Encoding and decoding in Java (encryption) and WLST

Faced with the need to encrypt passwords in a DB, I google and find this article, but then I realize it's not recommended (why?) to use sun.misc.BASE64Decoder, I should rather use Apache commons:

commons-codec-1.4.jar (in reality the latest release is not 1.4, but I don't care)

maven is:
<dependency>
 <groupId>commons-codec</groupId>
 <artifactId>commons-codec</artifactId>
 <version>1.4</version>
</dependency>
So I change implementation and I get this wonderful code:

package com.acme.osb.encryption;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

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


public class PasswordEncoder {

    private static final char[] PASSWORD = "enfldsgbnlsngdlksdsgm".toCharArray();
    private static final byte[] SALT = {
        (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12,
        (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12,
    };

    public static void main(String[] args) throws Exception {
        String originalPassword = "secret";
        System.out.println("Original password: " + originalPassword);
        String encryptedPassword = encrypt(originalPassword, PASSWORD);
        System.out.println("Encrypted password: " + encryptedPassword);
        String decryptedPassword = decrypt(encryptedPassword, PASSWORD);
        System.out.println("Decrypted password: " + decryptedPassword);
    }

    private static String encrypt(String property, char[] pw) throws GeneralSecurityException, UnsupportedEncodingException {
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
        SecretKey key = keyFactory.generateSecret(new PBEKeySpec(pw));
        Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
        pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
        return base64Encode(pbeCipher.doFinal(property.getBytes("UTF-8")));
    }

    private static String base64Encode(byte[] bytes) {
        return Base64.encodeBase64String(bytes);
    }

    private static String decrypt(String property, char[] pw) throws GeneralSecurityException, IOException {
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
        SecretKey key = keyFactory.generateSecret(new PBEKeySpec(pw));
        Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
        pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
        return new String(pbeCipher.doFinal(base64Decode(property)), "UTF-8");
    }

    private static byte[] base64Decode(String property) throws IOException {
        return Base64.decodeBase64(property);
    }

}




In WebLogic there is a simple way of encrypting/decrypting passwords, but for fear of depending from the SerializedSystemIni.dat file I am afraid of using it.
Here the official documentation.
Anyway just run . ./setDomainEnv.sh and then "java weblogic.security.Encrypt mypwtoencrypt". To decrypt, since WebLogic doesn't provide a "weblogic.security.Decrypt" utility, follow these steps

In WLST, to decode you can do the following:


from javax.crypto import Cipher
from javax.crypto import SecretKey
from javax.crypto import SecretKeyFactory
from javax.crypto.spec import PBEKeySpec
from javax.crypto.spec import PBEParameterSpec

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


def decode(encodedPassword):
    SALT='\xde\x33\x10\x12\xde\x33\x10\x12'
    key='yoursecretkeyhere'
    keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES")
    key = keyFactory.generateSecret(PBEKeySpec(key))
    pbeCipher = Cipher.getInstance("PBEWithMD5AndDES")
    
    pbeCipher.init(Cipher.DECRYPT_MODE, key, PBEParameterSpec(SALT, 20))
    
    resultb=pbeCipher.doFinal(Base64.decodeBase64(encodedPassword))
    
    print String(resultb, "utf-8")







No comments: