I'm cobol developer but I have to develop some code in java. I'm encrypting/decrypting strings in cobol usign hexadecimal values as encryption key and XOR operation. Those encrypted data are stored on a DB and then I have to read and decrypt them in java. I have no problem using ^ (xor) in java for those data encrypted with a key from 0x00 to 0x7F, the problem is when the key is from 0x80 to 0xFF (extended ASCII). I've read some posts (post1, post2) with a similar problem but I continue with the same problem.
In my code I'm trying to decode the encrypted data using the key 0x85 (character "…" in ASCII), it should return the data "desde cobol". With sql I'm getting the encypted value in a String, but its value in hex is 0xE1, 0xE0, 0xF6, 0xE1, 0xE0, 0xA5, 0xE6, 0xEA, 0xE7, 0xEA, 0xE9. (I would like to omit the sql code, but I don't know how to convert those hex into a string). How could I get the decrypted value 'desde cobol'?
import java.io.IOException;
import java.lang.Math;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.xml.bind.DatatypeConverter;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.util.Base64;
public class Decode02 {
public static void main(String args[]) {
//
Connection c = null;
Statement stmt = null;
String data = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:test2.db");
c.setAutoCommit(false);
System.out.println("Opened database successfully");
stmt = c.createStatement();
ResultSet rs = stmt.executeQuery( "SELECT * FROM tabla where key = '002';" );
while ( rs.next() ) {
String key = rs.getString("key");
data = rs.getString("data");
System.out.println( "CLAVE = " + key );
System.out.println( "DATOS = " + data );
System.out.println();
}
rs.close();
stmt.close();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Operation done successfully");
String shex = "85";
byte[] keyHex = DatatypeConverter.parseHexBinary(shex);
System.out.println("Byte: " + keyHex[0]);
byte[] bhex = new byte[0x85];
String keyStr = DatatypeConverter.printHexBinary(bhex);
System.out.println("String: " + keyStr);
System.out.println("");
String salida = new String(encode(data,shex));
System.out.println("Salida: " + salida);
String salida2 = new String(encode(data,keyStr));
System.out.println("Salida2: " + salida2);
System.out.println("");
}
public static String encode(String s, String key) {
return base64Encode(xorWithKey(s.getBytes(), key.getBytes()));
}
public static String decode(String s, String key) {
return new String(xorWithKey(base64Decode(s), key.getBytes()));
}
private static byte[] xorWithKey(byte[] a, byte[] key) {
byte[] out = new byte[a.length];
for (int i = 0; i < a.length; i++) {
out[i] = (byte) (a[i] ^ key[i%key.length]);
}
return out;
}
private static byte[] base64Decode(String s) {
try {
BASE64Decoder d = new BASE64Decoder();
return d.decodeBuffer(s);
} catch (IOException e) {throw new RuntimeException(e);}
}
private static String base64Encode(byte[] bytes) {
BASE64Encoder enc = new BASE64Encoder();
return enc.encode(bytes).replaceAll("\\s", "");
}
}
Output:
Opened database successfully
CLAVE = 002
DATOS = ??????????
Operation done successfully
cipher:
Byte: -123
String: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Decoded to be...
Salida: BwoHCgcKBwoHCg==
Salida2: Dw8PDw8PDw8PDw==