java.lang.NoClassDefFoundError: org/apache/commons/codec/binary/Base64 - java

Admin please don't mark it as duplicate read my question completely. I am encrypting and decrypting some text but while running in same file with main its running fine but when i call its encrypt and decrypt function from outside. Its giving an error at runtime. I am attaching the code.
package desede;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import security.SHA256Algo;
import shradhafinalwiddesign.UpdateFile;
import shradhafinalwiddesign.UserRegistration;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Simple TripleDES Encrypt/Decrypt Test
* sha1, utf-8, no padding
*
* uses commons-codec-1.6
* javac -cp :commons-codec-1.6.jar TripleDESTest.java
* java -cp :commons-codec-1.6.jar TripleDESTest
*/
public class TripleDesDemo {
public static void main(String[] args) throws Exception {
String text = "textToEncrypt";
UserRegistration user = new UserRegistration() ;
user.setlUsername("tarunv") ;
user.setAnswer("tommysdsfdsfsd") ;
user.setLastaccess("pets namesdfsfds") ;
user.setLpassword("computersdfdsfd") ;
String h1 = SHA256Algo.createHash(user.getlUsername()) ;
String h2 = SHA256Algo.createHash(user.getLpassword()) ;
String h3 = SHA256Algo.createHash(user.getAnswer()) ;
String hash1 = UpdateFile.modifyHashValue(h1).substring(0, 24) ;
String hash2 = UpdateFile.modifyHashValue(h2) ;
String hash3 = UpdateFile.modifyHashValue(h3) ;
System.out.println(" key1 : "+hash1.length()+" key2 : "+hash2.length()+" key3 : "+hash3.length());
byte[] arr = toByteArray(user) ;
byte[] codedtext = TripleDesDemo._encrypt(arr,"tarunvermacdac#gmail.com");
byte[] codedtext1 = TripleDesDemo._encrypt(codedtext,"tarun.spicyabc#gmail.com");
byte[] codedtext2 = TripleDesDemo._encrypt(codedtext1,"direct_tarun#yahoo.co.in");
writeSmallBinaryFile(codedtext2, "tarun.bat") ;
byte[] texttoDecrypt = readSmallBinaryFile("tarun.bat");
byte[] decodedtext = TripleDesDemo._decrypt(texttoDecrypt,"direct_tarun#yahoo.co.in");
byte[] decodedtext1 = TripleDesDemo._decrypt(decodedtext,"tarun.spicyabc#gmail.com");
byte[] decodedtext2 = TripleDesDemo._decrypt(decodedtext1,"tarunvermacdac#gmail.com");
System.out.println(codedtext + " ---> " + toObject(decodedtext2));
}
public static byte[] _encrypt(byte[] plainTextBytes, String secretKey) throws Exception {
byte[] keyBytes = secretKey.getBytes();
SecretKey key = new SecretKeySpec(keyBytes, "DESede");
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE, key);
//byte[] plainTextBytes = message.getBytes("utf-8");
byte[] buf = cipher.doFinal(plainTextBytes);
byte [] base64Bytes = Base64.encodeBase64(buf);
//String base64EncryptedString = new String(base64Bytes);
return base64Bytes ;
}
public static byte[] _decrypt(byte[] encryptedText, String secretKey) throws Exception {
//byte[] message = Base64.decodeBase64(encryptedText);
byte[] message = Base64.decodeBase64(encryptedText);
byte[] keyBytes = secretKey.getBytes();
SecretKey key = new SecretKeySpec(keyBytes, "DESede");
Cipher decipher = Cipher.getInstance("DESede");
decipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText = decipher.doFinal(message);
return plainText ;
//return toObject(plainText);
}
public static byte[] toByteArray(UserRegistration obj) throws IOException {
byte[] bytes = null;
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
try {
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
bytes = bos.toByteArray();
} finally {
if (oos != null) {
oos.close();
}
if (bos != null) {
bos.close();
}
}
return bytes;
}
public static UserRegistration toObject(byte[] bytes) throws IOException, ClassNotFoundException {
UserRegistration obj = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
bis = new ByteArrayInputStream(bytes);
ois = new ObjectInputStream(bis);
obj = (UserRegistration) ois.readObject();
} finally {
if (bis != null) {
bis.close();
}
if (ois != null) {
ois.close();
}
}
return obj;
}
public static byte[] readSmallBinaryFile(String aFileName) throws IOException {
Path path = Paths.get(aFileName);
return Files.readAllBytes(path);
}
public static void writeSmallBinaryFile(byte[] aBytes, String aFileName) throws IOException {
Path path = Paths.get(aFileName);
Files.write(path, aBytes); //creates, overwrites
}
}
The code is running fine with main but not when i call its function from other class which is in other package. Here is the exception.
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/apache/commons/codec/binary/Base64 at desede.TripleDesAlgo._encrypt(TripleDesAlgo.java:81)
And this is .classpath file
Thanks in advance for any help.

You are missing commons-codec.jar. Download it from http://commons.apache.org/proper/commons-codec/download_codec.cgi.
Then add it project build path. To do that right click the project, click Properties, click "Java Build Path", open "Library" tab, and click "Add External JARs...".
Or if you are using maven add dependency for
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.6</version>
</dependency>

Related

encoding and decoding international characters

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;
import com.Ostermiller.util.Base64;
import com.Ostermiller.util.MD5;
import java.net.URLEncoder;
public class EnDecryptor {
public static void addProvider()
{
if (Security.getProvider("IBMJCE") == null) {
// IBMJCE is not installed, install it.
try
{
Security.addProvider
((Provider)Class.forName("com.ibm.crypto.provider.IBMJCE").newInstance());
}
catch (Exception ex) {
AuthLogger.logFatal("EnDecryptor:addProvider():Cannot install provider: " + ex.getMessage());
}
}
}
public static String encrypt(String word)
{
addProvider();
String encWord="";
byte[] encryptedWordbytes=null;
try
{
if (null == word)
{
throw new NullPointerException("EnDecryptor:encrypt(): No string to be encrypted provided!");
}
AuthLogger.logDebug("EnDecryptor:encrypt():Generating an encryption key...");
encryptedWordbytes = MD5.getHash(word);
AuthLogger.logDebug("EnDecryptor:encrypt():MD5 HASH length:"+encryptedWordbytes.length);
AuthLogger.logDebug("EnDecryptor:encrypt():MD5 HASH :"+new String(encryptedWordbytes));
// Create a Rijndael key
SecretKeySpec KeySpec = new SecretKeySpec(encryptedWordbytes, "AES");
AuthLogger.logDebug("EnDecryptor:encrypt():Done generating the key...");
Cipher cipherKey =Cipher.getInstance("AES/CBC/PKCS5Padding", "IBMJCE");
byte[] iv = new byte[16];
IvParameterSpec spec = null;
for(int i=0;i<16;i++)
{
iv[i]=(byte)i;
}
spec = new IvParameterSpec(iv);
cipherKey.init(Cipher.ENCRYPT_MODE, KeySpec, spec);
byte[] encryptedDataBytes = cipherKey.doFinal(word.getBytes());
String base64data = new String(Base64.encode(encryptedDataBytes));
AuthLogger.logDebug("EnDecryptor:encrypt():BASE64DATA="+base64data);
byte[] encryptedKeyBytes = MD5.getHash(encryptedDataBytes);
SecretKeySpec KeySpec2 = new SecretKeySpec(encryptedKeyBytes, "AES");
Cipher cipherKey2 = Cipher.getInstance("AES/CBC/PKCS5Padding", "IBMJCE");//Cipher.getInstance(DataEncryptDecrypt.AlgEnc);
cipherKey2.init(Cipher.ENCRYPT_MODE, KeySpec2, spec);
byte[] encryptedkey = cipherKey2.doFinal(encryptedWordbytes);
String base64Key = new String(Base64.encode(encryptedkey));
AuthLogger.logDebug("EnDecryptor:encrypt():BASE64Key="+base64Key);
String parm1 = "Data=" + URLEncoder.encode(base64data, "UTF-8") ;//$$$ encode(base64data);
String parm2 = "A=" + URLEncoder.encode(base64Key, "UTF-8") ;//$$$ encode(base64Key);
//encWord="Data="+parm1+"&A="+parm2;
encWord=parm1+"&"+parm2;
}catch(Exception e)
{
e.printStackTrace();
}
return encWord;
}
public static String decrypt(String encData, String encKey)
{
addProvider();
String decryptedData="";
byte[] abKeysKey=null;
try
{
byte[] abEncryptedKeys=(Base64.decode(encKey.getBytes()));
if (null == encData)
{
throw new NullPointerException("EnDecryptor:decrypt(): No data to be decryopted provided!");
}
AuthLogger.logDebug("EnDecryptor:decrypt():Generating a the HASH of the data...");
abKeysKey = MD5.getHash(Base64.decode(encData.getBytes()));
// Create a Rijndael key
SecretKeySpec KeySpec = new SecretKeySpec(abKeysKey, "AES");
Cipher cipherKey = Cipher.getInstance("AES/CBC/PKCS5Padding", "IBMJCE");//Cipher.getInstance(DataEncryptDecrypt.AlgEnc);
IvParameterSpec spec = null;
byte[] iv = new byte[16];
for(int i=0;i<16;i++)
{
iv[i]=(byte)i;
}
spec = new IvParameterSpec(iv);
cipherKey.init(Cipher.DECRYPT_MODE, KeySpec, spec);
byte[] abKeys = cipherKey.doFinal(abEncryptedKeys);
String base64key = new String(Base64.encode(abKeys));
AuthLogger.logDebug("EnDecryptor:decrypt():BASE64 DECODED KEY="+base64key);
//byte[] encryptedKeyBytes = MD5.getHash(encryptedDataBytes);
SecretKeySpec KeySpec2 = new SecretKeySpec(abKeys, "AES");
Cipher cipherKey2 = Cipher.getInstance("AES/CBC/PKCS5Padding", "IBMJCE");//Cipher.getInstance(DataEncryptDecrypt.AlgEnc);
cipherKey2.init(Cipher.DECRYPT_MODE, KeySpec2, spec);
byte[] decodedData = cipherKey2.doFinal(Base64.decode(encData.getBytes()));
decryptedData= new String(decodedData);
AuthLogger.logDebug("EnDecryptor:decrypt():decoded data="+decryptedData);
}catch(Exception e)
{
e.printStackTrace();
}
return decryptedData;
}
}
in this code i can mostly encode A-Z and a-z, 0-9 and +,/ but i cannot encode any special characters like(~,#,!, etc) or international characters like(ê,etc)
can anyone suggest anything because i need to encode and decode characters like these any help will be appreciated.
New edit
if i use import java.io.IOException; will it solve my issue?
i know it's not good to use sun packages but i have done this it encodes mostly all the spacial and international characters except one or two here is the code
import java.io.IOException;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
// Java Base64 Encoder / Java Base64 Decoder
public class Base64Test {
public static void main(String[] args) {
BASE64Decoder decoder = new BASE64Decoder();
BASE64Encoder encoder = new BASE64Encoder();
try {
String encodedBytes = encoder.encodeBuffer("(####&&&&&)".getBytes());
System.out.println("encodedBytes " + encodedBytes);
byte[] decodedBytes = decoder.decodeBuffer(encodedBytes);
System.out.println("decodedBytes " + new String(decodedBytes));
} catch (IOException e) {
e.printStackTrace();
}
}
}
OUTPUT
encodedBytes KEBAQEAmJiYmJik=
decodedBytes (####&&&&&)

Converting TripleDes algorithm

I want to convert following C# to java code, so we can decrypt old messages and encrypt new ones in java.
public class encryptionUtil
{
private TripleDESCryptoServiceProvider TripleDes;
private UTF8Encoding utfEncoding;
private byte[] key;
private byte[] iv;
private string sysKey;
private string sysUser;
public encryptionUtil()
{
this.TripleDes = new TripleDESCryptoServiceProvider();
this.utfEncoding = new UTF8Encoding();
this.key = this.utfEncoding.GetBytes("123456789012345678901234");
this.iv = this.utfEncoding.GetBytes("12345678");
this.sysKey = WindowsIdentity.GetCurrent().Name;
this.sysUser = WindowsIdentity.GetCurrent().User.Value;
}
public string EncryptData(string plaintext)
{
string str;
try
{
plaintext = plaintext + this.sysUser;
byte[] bytes = Encoding.Unicode.GetBytes(plaintext);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream((Stream) memoryStream, this.TripleDes.CreateEncryptor(this.key, this.iv), CryptoStreamMode.Write);
cryptoStream.Write(bytes, 0, bytes.Length);
cryptoStream.FlushFinalBlock();
str = Convert.ToBase64String(memoryStream.ToArray());
}
catch (Exception ex)
{
ProjectData.SetProjectError(ex);
str = plaintext ;
ProjectData.ClearProjectError();
}
return str;
}
public string DecryptData(string encryptedtext)
{
string str;
try
{
byte[] buffer = Convert.FromBase64String(encryptedtext);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream((Stream) memoryStream, this.TripleDes.CreateDecryptor(this.key, this.iv), CryptoStreamMode.Write);
cryptoStream.Write(buffer, 0, buffer.Length);
cryptoStream.FlushFinalBlock();
string[] strArray = Encoding.Unicode.GetString(memoryStream.ToArray());
str = Microsoft.VisualBasic.CompilerServices.Operators.CompareString(strArray[1], this.token, false) != 0 ? "" : strArray[0];
}
catch (Exception ex)
{
ProjectData.SetProjectError(ex);
str = "";
ProjectData.ClearProjectError();
}
return str;
}
Encryption output in c# for "Encrypt this in java"
7UlYtjB6Nls4Q3Ac4VzdY2k6hVRa1Eqjyt2ZG4818WxLCwFhx1fEeTCvOStTylyMM5ucL4DmF1NKBRga44Yqrj89VHRKZuWnFC24jMkSxucZkB3niLa7WOT4GKlii7716w6TC9iJGYLhy8mY1kqwaw==
Java code written so far, how to proceed further so that I get same result as above?
package com.mycompany.util;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
public class EncryptionUtil {
private static SecretKey sharedkey;
private static byte [] sharedvector;
static {
int keySize = 168;
int ivSize = 8;
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
keyGenerator.init(keySize);
sharedkey = keyGenerator.generateKey();
sharedvector = new byte [ivSize];
byte [] data = sharedkey.getEncoded();
int half = ivSize / 2;
System.arraycopy(data, data.length-half, sharedvector, 0, half);
System.arraycopy(sharedvector, 0, sharedvector, half, half);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
public static void main(String [] args) throws Exception {
String plainText = "Encrypt this in java";
String systemId= "949367136-5890454";
String dataText = plainText+systemId
String keyString = "key1234";
String ivString = "iv1234";
try {
byte[] keyBytes = keyString.getBytes("UTF-8");
byte[] ivBytes = ivString.getBytes("UTF-8");
byte[] dataBytes = plainText.getBytes("UTF-8");
System.out.println("key="+keyBytes.toString());
System.out.println("iv="+ivBytes.toString());
System.out.println("plaintextBytesUTF-8="+dataBytes.toString());
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String Encrypt(String val) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, sharedkey, new IvParameterSpec(sharedvector));
return new sun.misc.BASE64Encoder().encode(cipher.doFinal(val.getBytes()));
}
public static String Decrypt(String val) throws GeneralSecurityException, IOException {
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, sharedkey, new IvParameterSpec(sharedvector));
return new String(cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(val)));
}
}

NullPointerException exception when encrypting and serializing [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I'm trying to encrypt an ArrayList type and serialize it. Following is my code.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import premierleague.model.FootballClub;
import premierleague.model.Match;
/**
*
* #author Akila
*/
public class Serializing implements Serializable{
private FileInputStream fileIn;
private FileOutputStream fileOut;
private ObjectInputStream in;
private ObjectOutputStream out;
public ArrayList<FootballClub> FootBallInputStream() throws FileNotFoundException, IOException, ClassNotFoundException, NoSuchAlgorithmException, NoSuchPaddingException {
Cipher cipher = Cipher.getInstance("DES");
File file = new File("FootballClub.ser");
fileIn = new FileInputStream(file);
CipherInputStream CipherIn = new CipherInputStream(in, cipher);
in = new ObjectInputStream(CipherIn);
ArrayList<FootballClub> e = (ArrayList<FootballClub>) in.readObject();
in.close();
fileIn.close();
return e;
}
public void FootBallOutputStream(ArrayList<FootballClub> e) throws FileNotFoundException, IOException, NoSuchAlgorithmException, NoSuchPaddingException {
Cipher cipher = Cipher.getInstance("DES");
File file = new File("FootballClub.ser");
fileOut = new FileOutputStream(file);
CipherOutputStream cipherOut = new CipherOutputStream(out,cipher);
out = new ObjectOutputStream(cipherOut);
out.writeObject(e);
out.close();
fileOut.close();
}
}
Although i get a NullPointer exception when trying to use the these methods.
Exception in thread "main" java.lang.NullPointerException
at javax.crypto.CipherInputStream.getMoreData(CipherInputStream.java:103)
at javax.crypto.CipherInputStream.read(CipherInputStream.java:224)
at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2289)
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2302)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2773)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:798)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:298)
at premierleague.controller.Serializing.FootBallInputStream(Serializing.java:41)
I've already initiaized CipherInputStream object and ObjectInputStream object. Yet, it throws me a null pointer exception
EDIT
public ArrayList<FootballClub> FootBallInputStream() throws FileNotFoundException, IOException, ClassNotFoundException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
File file = new File("FootballClub.ser");
fileIn = new FileInputStream(file);
CipherInputStream CipherIn = new CipherInputStream(fileIn, cipher);
in = new ObjectInputStream(CipherIn);
ArrayList<FootballClub> e = (ArrayList<FootballClub>) in.readObject();
in.close();
fileIn.close();
return e;
}
public void FootBallOutputStream(ArrayList<FootballClub> e) throws FileNotFoundException, IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
Cipher cipher = (Cipher.getInstance("DES"));
cipher.init(Cipher.ENCRYPT_MODE, key);
File file = new File("FootballClub.ser");
fileOut = new FileOutputStream(file);
CipherOutputStream cipherOut = new CipherOutputStream(fileOut, cipher);
out = new ObjectOutputStream(cipherOut);
out.writeObject(e);
out.close();
fileOut.close();
}
Exception
Exception in thread "main" java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2304)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2773)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:798)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:298)
at premierleague.controller.Serializing.FootBallInputStream(Serializing.java:47)
FootballClub Class
package premierleague.model;
/**
*
* #author Akila
*/
public class FootballClub extends SportsClub implements Comparable<FootballClub>{
private int wins;
private int defeats;
private int draws;
private int currentPoints=0;
private int goalsRecieved;
private int goalsScored;
// public FootballClub(String name, String location) {
// super.getClubName()= ;
// super.getLocation()= location;
//
// }
public int getWins() {
return wins;
}
public void setWins(int wins) {
this.wins = wins;
}
public int getDefeats() {
return defeats;
}
public void setDefeats(int defeats) {
this.defeats = defeats;
}
public int getDraws() {
return draws;
}
public void setDraws(int draws) {
this.draws = draws;
}
public int getCurrentPoints() {
return currentPoints;
}
public void setCurrentPoints(int currentPoints) {
this.currentPoints = currentPoints;
}
public int getGoalsRecieved() {
return goalsRecieved;
}
public void setGoalsRecieved(int goalsRecieved) {
this.goalsRecieved = goalsRecieved;
}
public int getGoalsScored() {
return goalsScored;
}
public void setGoalsScored(int goalsScored) {
this.goalsScored = goalsScored;
}
// #Override
// public int compareTo(FootballClub o) {
// if (this.getCurrentPoints()> o.getCurrentPoints()) {
// return 1;
//
// }else if (this.getCurrentPoints()== o.getCurrentPoints()){
// if (this.getCurrentPoints()> o.getCurrentPoints()) {
// return 1;
//
// }else{
// return -1;
// }
// }else{
// return -1;
// }
//
// }
//
#Override
public int compareTo(FootballClub o) {
if(this.getCurrentPoints()>o.getCurrentPoints()){
return 1;
}else if(this.getCurrentPoints()==o.getCurrentPoints()){
if(this.getCurrentPoints()>o.getCurrentPoints()){
return 1;
}else {
return -1;
}
}else{
return -1;
}
}
public static final long serialVersionUID = 948599023243074087L;
}
NEW EDIT
public ArrayList<FootballClub> FootBallInputStream() throws FileNotFoundException, IOException, ClassNotFoundException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
File file = new File("FootballClub.ser");
fileIn = new FileInputStream(file);
SecretKey key = KeyGenerator.getInstance("AES").generateKey();
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
CipherInputStream cipherIn = new CipherInputStream(fileIn, cipher);
in = new ObjectInputStream(cipherIn);
SealedObject sealed = (SealedObject) in.readObject();
ArrayList<FootballClub> e = (ArrayList<FootballClub>) sealed.getObject(cipher);
in.close();
fileIn.close();
return e;
}
public void FootBallOutputStream(ArrayList<FootballClub> e) throws FileNotFoundException, IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException {
File file = new File("FootballClub.ser");
fileOut = new FileOutputStream(file);
SecretKey key = KeyGenerator.getInstance("AES").generateKey();
Cipher cipher = (Cipher.getInstance("AES"));
cipher.init(Cipher.ENCRYPT_MODE, key);
SealedObject sealed = new SealedObject(e, cipher);
CipherOutputStream cipherOut = new CipherOutputStream(fileOut, cipher);
out = new ObjectOutputStream(cipherOut);
out.writeObject(sealed);
out.close();
fileOut.close();
}
NEW EXCEPTION
Exception in thread "main" java.io.StreamCorruptedException: invalid stream header: CF8CA0C1
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:801)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:298)
at premierleague.controller.Serializing.FootBallInputStream(Serializing.java:54)
try
cipher = Cipher.getInstance("DES")
instead of
Cipher cipher = Cipher.getInstance("DES");
also maybe check your brackets and you're returning something in the first method but their is no return type

3DES Encryption Oracle/JAVA equivalent

I'm trying to migrate the oracle method dbms_obfuscation_toolkit.DES3Encrypt to a Java Function. My problem is that I don't get the same encrypted value in both scenes.
For this procedure in Oracle:
set serveroutput on;
declare
input raw(128);
encrypted raw(2048);
cadena varchar2(60);
begin
dbms_obfuscation_toolkit.DES3Encrypt(
input => utl_raw.cast_to_raw('TESTDATATESTDATATESTDATA'),
key => utl_raw.cast_to_raw('GD6GTT56HKY4HGF6FH3JG9J5F62FT1'),
encrypted_data => encrypted
);
dbms_output.put_line(rawtohex(encrypted));
end;
I get this output:
8A2E6792E39B0C850377F9A0E054033963F979E4A3FBA25B
However, with this Java class:
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
public class TripleDes2
{
private static final String PLAIN_TEXT = "TESTDATATESTDATATESTDATA";
private static final String SHARED_KEY = "GD6GTT56HKY4HGF6FH3JG9J5F62FT1";
public static void main(String args []) throws Exception
{
String algorithm = "DESede";
String transformation = "DESede/CBC/PKCS5Padding";
byte[] keyValue = SHARED_KEY.getBytes("UTF-8");
DESedeKeySpec keySpec = new DESedeKeySpec(keyValue);
IvParameterSpec iv = new IvParameterSpec(new byte[8]);
SecretKey key = SecretKeyFactory.getInstance(algorithm).generateSecret(keySpec);
Cipher encrypter = Cipher.getInstance(transformation);
encrypter.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] input = PLAIN_TEXT.getBytes("UTF-8");
byte[] encrypted = encrypter.doFinal(input);
System.out.println(new String(Hex.encodeHex(encrypted)).toUpperCase());
}
}
I'm getting this value:
82EBC149F298DE55E4FF1540615E60ACDB7743FE79CD2CF4BB6FD232893F83D0
I'm not sure if my Java Code is right. Can you help me?
Thank you very much.
This is my final code, it works like a charm:
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
public class TripleDes3 {
private Cipher cipher = null;
private SecretKey key = null;
private byte[] bytes = null;
private IvParameterSpec iv = null;
public static void main(String[] args) throws Exception {
try {
String hexKey = "GD6GTT56HKY4HGF6FH3JG9J5";
//TripleDes3 encryptor = new TripleDes3(new String(Hex.decodeHex(hexKey.toCharArray())));
TripleDes3 encryptor = new TripleDes3(hexKey);
String original = "ABC";
System.out.println("Oringal: \"" + original + "\"");
String enc = encryptor.encrypt(original);
System.out.println("Encrypted: \"" + enc.toUpperCase() + "\"");
String dec = encryptor.decrypt(enc);
System.out.println("Decrypted: \"" + dec.toUpperCase() + "\"");
if (dec.equals(original)) {
System.out.println("Encryption ==> Decryption Successful");
}
} catch (Exception e) {
System.out.println("Error: " + e.toString());
}
}
public TripleDes3(String encryptionKey) throws GeneralSecurityException, DecoderException {
cipher = Cipher.getInstance("DESede/CBC/NoPadding");
try {
key = new SecretKeySpec(encryptionKey.getBytes("ISO8859_15"), "DESede");
iv = new IvParameterSpec(Hex.decodeHex("0123456789abcdef".toCharArray()));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String encrypt(String input) throws GeneralSecurityException, UnsupportedEncodingException {
bytes = input.getBytes("ISO8859_15");
bytes = Arrays.copyOf(bytes, ((bytes.length+7)/8)*8);
return new String(Hex.encodeHex(encryptB(bytes)));
}
public String decrypt(String input) throws GeneralSecurityException, DecoderException, UnsupportedEncodingException {
bytes = Hex.decodeHex(input.toCharArray());
String decrypted = new String(decryptB(bytes), "ISO8859_15");
if (decrypted.indexOf((char) 0) > 0) {
decrypted = decrypted.substring(0, decrypted.indexOf((char) 0));
}
return decrypted;
}
public byte[] encryptB(byte[] bytes) throws GeneralSecurityException {
cipher.init(Cipher.ENCRYPT_MODE, (Key) key, iv);
return cipher.doFinal(bytes);
}
public byte[] decryptB(byte[] bytes) throws GeneralSecurityException {
cipher.init(Cipher.DECRYPT_MODE, (Key) key, iv);
return cipher.doFinal(bytes);
}
}
And this is the Oracle Code:
DECLARE
v_data VARCHAR2(255);
v_retval RAW(255);
p_str VARCHAR2(255);
p_key RAW(255);
BEGIN
p_str := 'ABC';
p_key := utl_raw.cast_to_raw('GD6GTT56HKY4HGF6FH3JG9J5F62FT1');
v_data := RPAD(p_str, CEIL(LENGTH(p_str)/8)*8, CHR(0));
dbms_obfuscation_toolkit.DES3Encrypt
(
input => utl_raw.cast_to_raw(v_data),
key => p_key,
which => 1,
encrypted_data => v_retval
);
dbms_output.put_line(v_retval);
END;

Java Equivalent to OpenSSL AES [duplicate]

I need to decrypt in JAVA a file encrypted in UNIX with the following command:
openssl aes-256-cbc -a -salt -in password.txt -out password.txt.enc
mypass
mypass
I have to decrypt in java as I do here I do in UNIX
openssl aes-256-cbc -d -a -in password.txt.enc -out password.txt.new
mypass
Someone can give me a java code to do this?
OpenSSL generally uses its own password based key derivation method, specified in EVP_BytesToKey, please see the code below. Furthermore, it implicitly encodes the ciphertext as base 64 over multiple lines, which would be required to send it within the body of a mail message.
So the result is, in pseudocode:
salt = random(8)
keyAndIV = BytesToKey(password, salt, 48)
key = keyAndIV[0..31]
iv = keyAndIV[32..47]
ct = AES-256-CBC-encrypt(key, iv, plaintext)
res = base64MimeEncode("Salted__" | salt | ct))
and the decryption therefore is:
(salt, ct) = base64MimeDecode(res)
key = keyAndIV[0..31]
iv = keyAndIV[32..47]
pt = AES-256-CBC-decrypt(key, iv, plaintext)
which can be implemented in Java like this:
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.List;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.util.encoders.Base64;
public class OpenSSLDecryptor {
private static final Charset ASCII = Charset.forName("ASCII");
private static final int INDEX_KEY = 0;
private static final int INDEX_IV = 1;
private static final int ITERATIONS = 1;
private static final int ARG_INDEX_FILENAME = 0;
private static final int ARG_INDEX_PASSWORD = 1;
private static final int SALT_OFFSET = 8;
private static final int SALT_SIZE = 8;
private static final int CIPHERTEXT_OFFSET = SALT_OFFSET + SALT_SIZE;
private static final int KEY_SIZE_BITS = 256;
/**
* Thanks go to Ola Bini for releasing this source on his blog.
* The source was obtained from here .
*/
public static byte[][] EVP_BytesToKey(int key_len, int iv_len, MessageDigest md,
byte[] salt, byte[] data, int count) {
byte[][] both = new byte[2][];
byte[] key = new byte[key_len];
int key_ix = 0;
byte[] iv = new byte[iv_len];
int iv_ix = 0;
both[0] = key;
both[1] = iv;
byte[] md_buf = null;
int nkey = key_len;
int niv = iv_len;
int i = 0;
if (data == null) {
return both;
}
int addmd = 0;
for (;;) {
md.reset();
if (addmd++ > 0) {
md.update(md_buf);
}
md.update(data);
if (null != salt) {
md.update(salt, 0, 8);
}
md_buf = md.digest();
for (i = 1; i < count; i++) {
md.reset();
md.update(md_buf);
md_buf = md.digest();
}
i = 0;
if (nkey > 0) {
for (;;) {
if (nkey == 0)
break;
if (i == md_buf.length)
break;
key[key_ix++] = md_buf[i];
nkey--;
i++;
}
}
if (niv > 0 && i != md_buf.length) {
for (;;) {
if (niv == 0)
break;
if (i == md_buf.length)
break;
iv[iv_ix++] = md_buf[i];
niv--;
i++;
}
}
if (nkey == 0 && niv == 0) {
break;
}
}
for (i = 0; i < md_buf.length; i++) {
md_buf[i] = 0;
}
return both;
}
public static void main(String[] args) {
try {
// --- read base 64 encoded file ---
File f = new File(args[ARG_INDEX_FILENAME]);
List<String> lines = Files.readAllLines(f.toPath(), ASCII);
StringBuilder sb = new StringBuilder();
for (String line : lines) {
sb.append(line.trim());
}
String dataBase64 = sb.toString();
byte[] headerSaltAndCipherText = Base64.decode(dataBase64);
// --- extract salt & encrypted ---
// header is "Salted__", ASCII encoded, if salt is being used (the default)
byte[] salt = Arrays.copyOfRange(
headerSaltAndCipherText, SALT_OFFSET, SALT_OFFSET + SALT_SIZE);
byte[] encrypted = Arrays.copyOfRange(
headerSaltAndCipherText, CIPHERTEXT_OFFSET, headerSaltAndCipherText.length);
// --- specify cipher and digest for EVP_BytesToKey method ---
Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");
MessageDigest md5 = MessageDigest.getInstance("MD5");
// --- create key and IV ---
// the IV is useless, OpenSSL might as well have use zero's
final byte[][] keyAndIV = EVP_BytesToKey(
KEY_SIZE_BITS / Byte.SIZE,
aesCBC.getBlockSize(),
md5,
salt,
args[ARG_INDEX_PASSWORD].getBytes(ASCII),
ITERATIONS);
SecretKeySpec key = new SecretKeySpec(keyAndIV[INDEX_KEY], "AES");
IvParameterSpec iv = new IvParameterSpec(keyAndIV[INDEX_IV]);
// --- initialize cipher instance and decrypt ---
aesCBC.init(Cipher.DECRYPT_MODE, key, iv);
byte[] decrypted = aesCBC.doFinal(encrypted);
String answer = new String(decrypted, ASCII);
System.out.println(answer);
} catch (BadPaddingException e) {
// AKA "something went wrong"
throw new IllegalStateException(
"Bad password, algorithm, mode or padding;" +
" no salt, wrong number of iterations or corrupted ciphertext.");
} catch (IllegalBlockSizeException e) {
throw new IllegalStateException(
"Bad algorithm, mode or corrupted (resized) ciphertext.");
} catch (GeneralSecurityException e) {
throw new IllegalStateException(e);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}
Beware that the code specifies ASCII as character set. The character set used may differ for your application / terminal / OS.
In general you should force OpenSSL to use the NIST approved PBKDF2 algorithm, as using the OpenSSL key derivation method - with an iteration count of 1 - is insecure. This may force you to use a different solution than OpenSSL. Note that password based encryption is inherently rather insecure - passwords are much less secure than randomly generated symmetric keys.
OpenSSL 1.1.0c changed the digest algorithm used in some internal components. Formerly, MD5 was used, and 1.1.0 switched to SHA256. Be careful the change is not affecting you in both EVP_BytesToKey and commands like openssl enc.
It's probably best to explicitly specify the digest in the command line interface (e.g. -md md5 for backwards compatibility or sha-256 for forwards compatibility) for the and make sure that the Java code uses the same digest algorithm ("MD5" or "SHA-256" including the dash). Also see the information in this answer.
Below are OpenSSLPBEInputStream and OpenSSLPBEOutputStream which can be used to encrypt/decrypt arbitrary streams of bytes in a way that is compatible with OpenSSL.
Example usage:
// The original clear text bytes
byte[] originalBytes = ...
// Encrypt these bytes
char[] pwd = "thePassword".toCharArray();
ByteArrayOutputStream byteOS = new ByteArrayOutputStream();
OpenSSLPBEOutputStream encOS = new OpenSSLPBEOutputStream(byteOS, ALGORITHM, 1, pwd);
encOS.write(originalBytes);
encOS.flush();
byte[] encryptedBytes = byteOS.toByteArray();
// Decrypt the bytes
ByteArrayInputStream byteIS = new ByteArrayInputStream(encryptedBytes);
OpenSSLPBEInputStream encIS = new OpenSSLPBEInputStream(byteIS, ALGORITHM, 1, pwd);
Where ALGORITHM (using just JDK classes) can be: "PBEWithMD5AndDES", "PBEWithMD5AndTripleDES", "PBEWithSHA1AndDESede", "PBEWithSHA1AndRC2_40".
To handle "openssl aes-256-cbc -a -salt -in password.txt -out password.txt.enc" of the original poster, add bouncey castle to the classpath, and use algorthm= "PBEWITHMD5AND256BITAES-CBC-OPENSSL".
/* Add BC provider, and fail fast if BC provider is not in classpath for some reason */
Security.addProvider(new BouncyCastleProvider());
The dependency:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.44</version>
</dependency>
The input stream:
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
public class OpenSSLPBEInputStream extends InputStream {
private final static int READ_BLOCK_SIZE = 64 * 1024;
private final Cipher cipher;
private final InputStream inStream;
private final byte[] bufferCipher = new byte[READ_BLOCK_SIZE];
private byte[] bufferClear = null;
private int index = Integer.MAX_VALUE;
private int maxIndex = 0;
public OpenSSLPBEInputStream(final InputStream streamIn, String algIn, int iterationCount, char[] password)
throws IOException {
this.inStream = streamIn;
try {
byte[] salt = readSalt();
cipher = OpenSSLPBECommon.initializeCipher(password, salt, Cipher.DECRYPT_MODE, algIn, iterationCount);
} catch (InvalidKeySpecException | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException e) {
throw new IOException(e);
}
}
#Override
public int available() throws IOException {
return inStream.available();
}
#Override
public int read() throws IOException {
if (index > maxIndex) {
index = 0;
int read = inStream.read(bufferCipher);
if (read != -1) {
bufferClear = cipher.update(bufferCipher, 0, read);
}
if (read == -1 || bufferClear == null || bufferClear.length == 0) {
try {
bufferClear = cipher.doFinal();
} catch (IllegalBlockSizeException | BadPaddingException e) {
bufferClear = null;
}
}
if (bufferClear == null || bufferClear.length == 0) {
return -1;
}
maxIndex = bufferClear.length - 1;
}
return bufferClear[index++] & 0xff;
}
private byte[] readSalt() throws IOException {
byte[] headerBytes = new byte[OpenSSLPBECommon.OPENSSL_HEADER_STRING.length()];
inStream.read(headerBytes);
String headerString = new String(headerBytes, OpenSSLPBECommon.OPENSSL_HEADER_ENCODE);
if (!OpenSSLPBECommon.OPENSSL_HEADER_STRING.equals(headerString)) {
throw new IOException("unexpected file header " + headerString);
}
byte[] salt = new byte[OpenSSLPBECommon.SALT_SIZE_BYTES];
inStream.read(salt);
return salt;
}
}
The output stream:
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.io.OutputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
public class OpenSSLPBEOutputStream extends OutputStream {
private static final int BUFFER_SIZE = 5 * 1024 * 1024;
private final Cipher cipher;
private final OutputStream outStream;
private final byte[] buffer = new byte[BUFFER_SIZE];
private int bufferIndex = 0;
public OpenSSLPBEOutputStream(final OutputStream outputStream, String algIn, int iterationCount,
char[] password) throws IOException {
outStream = outputStream;
try {
/* Create and use a random SALT for each instance of this output stream. */
byte[] salt = new byte[PBECommon.SALT_SIZE_BYTES];
new SecureRandom().nextBytes(salt);
cipher = OpenSSLPBECommon.initializeCipher(password, salt, Cipher.ENCRYPT_MODE, algIn, iterationCount);
/* Write header */
writeHeader(salt);
} catch (InvalidKeySpecException | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException e) {
throw new IOException(e);
}
}
#Override
public void write(int b) throws IOException {
buffer[bufferIndex] = (byte) b;
bufferIndex++;
if (bufferIndex == BUFFER_SIZE) {
byte[] result = cipher.update(buffer, 0, bufferIndex);
outStream.write(result);
bufferIndex = 0;
}
}
#Override
public void flush() throws IOException {
if (bufferIndex > 0) {
byte[] result;
try {
result = cipher.doFinal(buffer, 0, bufferIndex);
outStream.write(result);
} catch (IllegalBlockSizeException | BadPaddingException e) {
throw new IOException(e);
}
bufferIndex = 0;
}
}
#Override
public void close() throws IOException {
flush();
outStream.close();
}
private void writeHeader(byte[] salt) throws IOException {
outStream.write(OpenSSLPBECommon.OPENSSL_HEADER_STRING.getBytes(OpenSSLPBECommon.OPENSSL_HEADER_ENCODE));
outStream.write(salt);
}
}
Small common class:
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
class OpenSSLPBECommon {
protected static final int SALT_SIZE_BYTES = 8;
protected static final String OPENSSL_HEADER_STRING = "Salted__";
protected static final String OPENSSL_HEADER_ENCODE = "ASCII";
protected static Cipher initializeCipher(char[] password, byte[] salt, int cipherMode,
final String algorithm, int iterationCount) throws NoSuchAlgorithmException, InvalidKeySpecException,
InvalidKeyException, NoSuchPaddingException, InvalidAlgorithmParameterException {
PBEKeySpec keySpec = new PBEKeySpec(password);
SecretKeyFactory factory = SecretKeyFactory.getInstance(algorithm);
SecretKey key = factory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(cipherMode, key, new PBEParameterSpec(salt, iterationCount));
return cipher;
}
}
In Kotlin:
package io.matthewnelson.java_crypto
import java.util.*
import javax.crypto.Cipher
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.PBEKeySpec
import javax.crypto.spec.SecretKeySpec
class OpenSSL {
/**
* Will decrypt a string value encrypted by OpenSSL v 1.1.1+ using the following cmds from terminal:
*
* echo "Hello World!" | openssl aes-256-cbc -e -a -p -salt -pbkdf2 -iter 15739 -k qk4aX-EfMUa-g4HdF-fjfkU-bbLNx-15739
*
* Terminal output:
* salt=CC73B7D29FE59CE1
* key=31706F84185EA4B5E8E040F2C813F79722F22996B48B82FF98174F887A9B9993
* iv =1420310D41FD7F48E5D8722B9AC1C8DD
* U2FsdGVkX1/Mc7fSn+Wc4XLwDsmLdR8O7K3bFPpCglA=
* */
fun decrypt_AES256CBC_PBKDF2_HMAC_SHA256(
password: String,
hashIterations: Int,
encryptedString: String
): String {
val encryptedBytes = Base64.getDecoder().decode(encryptedString)
// Salt is bytes 8 - 15
val salt = encryptedBytes.copyOfRange(8, 16)
// println("Salt: ${salt.joinToString("") { "%02X".format(it) }}")
// Derive 48 byte key
val keySpec = PBEKeySpec(password.toCharArray(), salt, hashIterations, 48 * 8)
val keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
val secretKey = keyFactory.generateSecret(keySpec)
// Decryption Key is bytes 0 - 31 of the derived key
val key = secretKey.encoded.copyOfRange(0, 32)
// println("Key: ${key.joinToString("") { "%02X".format(it) }}")
// Input Vector is bytes 32 - 47 of the derived key
val iv = secretKey.encoded.copyOfRange(32, 48)
// println("IV: ${iv.joinToString("") { "%02X".format(it) }}")
// Cipher Text is bytes 16 - end of the encrypted bytes
val cipherText = encryptedBytes.copyOfRange(16, encryptedBytes.lastIndex + 1)
// Decrypt the Cipher Text and manually remove padding after
val cipher = Cipher.getInstance("AES/CBC/NoPadding")
cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(key, "AES"), IvParameterSpec(iv))
val decrypted = cipher.doFinal(cipherText)
// println("Decrypted: ${decrypted.joinToString("") { "%02X".format(it) }}")
// Last byte of the decrypted text is the number of padding bytes needed to remove
val plaintext = decrypted.copyOfRange(0, decrypted.lastIndex + 1 - decrypted.last().toInt())
return plaintext.toString(Charsets.UTF_8)
}
}
Don't use ase-128-cbc, use ase-128-ecb.
only take first 16 bytes as key because key is 128 bits
hash output is printed in hex, which every 2 chars presents a byte value
hashpwd=echo -n $password| openssl sha1 | sed 's#.*=\\s*##g' | cut -c 1-32
openssl enc -aes-128-ecb -salt -in -out -K $hashpwd
Java Code is here:
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
//openssl enc -nosalt -aes-128-ecb
// -in <input file>
// -out <output file>
// -K <16 bytes in hex, for example : "abc" can be hashed in SHA-1, the first 16 bytes in hex is a9993e364706816aba3e25717850c26c>
private final static String TRANSFORMATION = "AES"; // use aes-128-ecb in openssl
public static byte[] encrypt(String passcode, byte[] data) throws CryptographicException {
try {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, genKeySpec(passcode));
return cipher.doFinal(data);
} catch (Exception ex) {
throw new CryptographicException("Error encrypting", ex);
}
}
public static String encryptWithBase64(String passcode, byte[] data) throws CryptographicException {
return new BASE64Encoder().encode(encrypt(passcode, data));
}
public static byte[] decrypt(String passcode, byte[] data) throws CryptographicException {
try {
Cipher dcipher = Cipher.getInstance(TRANSFORMATION);
dcipher.init(Cipher.DECRYPT_MODE, genKeySpec(passcode));
return dcipher.doFinal(data);
} catch (Exception e) {
throw new CryptographicException("Error decrypting", e);
}
}
public static byte[] decryptWithBase64(String passcode, String encrptedStr) throws CryptographicException {
try {
return decrypt(passcode, new BASE64Decoder().decodeBuffer(encrptedStr));
} catch (Exception e) {
throw new CryptographicException("Error decrypting", e);
}
}
public static SecretKeySpec genKeySpec(String passcode) throws UnsupportedEncodingException, NoSuchAlgorithmException {
byte[] key = passcode.getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit
return new SecretKeySpec(key, TRANSFORMATION);
}
Tested and passed in jdk6 and jdk8.

Categories