AES 128 Encryption in Angular 4 and decryption in Java - java

I am using a CryptoJS(AES) for encryption in Angular 4 using below code:
const key = CryptoJS.enc.Utf8.parse('7061737323313233');
const iv = CryptoJS.enc.Utf8.parse('7061737323313233');
const encrypted = CryptoJS.AES.encrypt('String to encrypt', key, {
keySize: 16,
iv: iv,
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
console.log('Encrypted :' + encrypted);
and below java code to decrypt using AES:
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Encryption {
private static SecretKeySpec secretKey;
private static byte[] key;
public static void setKey(String myKey)
{
MessageDigest sha = null;
try {
key = myKey.getBytes("UTF-8");
sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
secretKey = new SecretKeySpec(key, "AES");
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
public static String encrypt(String strToEncrypt, String secret)
{
try
{
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
}
catch (Exception e)
{
System.out.println("Error while encrypting: " + e.toString());
}
return null;
}
public static String decrypt(String strToDecrypt, String secret)
{
try
{
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
}
catch (Exception e)
{
System.out.println("Error while decrypting: " + e.toString());
}
return null;
}
}
and
public class Test {
public static void main(String[] args) {
final String secretKey = "7061737323313233";
String originalString = "Response from angular";
String decryptedString = Encryption.decrypt(originalString, secretKey);
System.out.println(decryptedString);
}
}
Angular and java both code works fine if i run it independently for Encryption and Decryption. but when i encrypt using angular and decrypt using java it gives error:
Error while decrypting: javax.crypto.BadPaddingException: Given final block not properly padded
Now my issues are there is a diffrence of padding in angular and java. In angular it is Pkcs7 and in java it is Pkcs5 but this link Padding
says both are same then, why this error is comming. Please help me

My code to generate key was generating bad key in java. So i changed it to :
Key key = new SecretKeySpec(key.getBytes("UTF-8"),"AES" );
Now its working fine

This is a little problematic because of the difference in Javascript and Java libraries.
Please follow the below code which worked for me and I was successfully able to encrypt the data in Java and decrypt in Java.
import java.security.Key;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Crypt {
private static final String ALGO = "AES"; // Default uses ECB PKCS5Padding
public static String encrypt(String Data, String secret) throws Exception {
Key key = generateKey(secret);
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(Data.getBytes());
String encryptedValue = Base64.getEncoder().encodeToString(encVal);
return encryptedValue;
}
public static String decrypt(String strToDecrypt, String secret) {
try {
Key key = generateKey(secret);
Cipher cipher = Cipher.getInstance(ALGO);
cipher.init(Cipher.DECRYPT_MODE, key);
return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
} catch (Exception e) {
System.out.println("Error while decrypting: " + e.toString());
}
return null;
}
private static Key generateKey(String secret) throws Exception {
byte[] decoded = Base64.getDecoder().decode(secret.getBytes());
Key key = new SecretKeySpec(decoded, ALGO);
return key;
}
public static String decodeKey(String str) {
byte[] decoded = Base64.getDecoder().decode(str.getBytes());
return new String(decoded);
}
public static String encodeKey(String str) {
byte[] encoded = Base64.getEncoder().encode(str.getBytes());
return new String(encoded);
}
public static void main(String a[]) throws Exception {
/*
* Secret Key must be in the form of 16 byte like,
*
* private static final byte[] secretKey = new byte[] { ‘m’, ‘u’, ‘s’, ‘t’, ‘b’,
* ‘e’, ‘1’, ‘6’, ‘b’, ‘y’, ‘t’,’e’, ‘s’, ‘k’, ‘e’, ‘y’};
*
* below is the direct 16byte string we can use
*/
String secretKey = "mustbe16byteskey";
String encodedBase64Key = encodeKey(secretKey);
System.out.println("EncodedBase64Key = " + encodedBase64Key); // This need to be share between client and server
// To check actual key from encoded base 64 secretKey
// String toDecodeBase64Key = decodeKey(encodedBase64Key);
// System.out.println("toDecodeBase64Key = "+toDecodeBase64Key);
String toEncrypt = "Please encrypt this message!";
System.out.println("Plain text = " + toEncrypt);
// AES Encryption based on above secretKey
String encrStr = Crypt.encrypt(toEncrypt, encodedBase64Key);
System.out.println("Cipher Text: Encryption of str = " + encrStr);
// AES Decryption based on above secretKey
String decrStr = Crypt.decrypt(encrStr, encodedBase64Key);
System.out.println("Decryption of str = " + decrStr);
}
}
<!DOCTYPE html>
<html>
<body>
<h2>Java JavaScript Encryption & Decryption</h2>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
<script type="text/javascript">
console.log('crypto - js’, CryptoJS);
var encryptedBase64Key = 'bXVzdGJlMTZieXRlc2tleQ==’;
var parsedBase64Key = CryptoJS.enc.Base64.parse(encryptedBase64Key);
var encryptedData = null;
{
// Encryption process
var plaintText = "Please encrypt this message!”;
// console.log( "plaintText = " + plaintText );
// this is Base64-encoded encrypted data
encryptedData = CryptoJS.AES.encrypt(plaintText, parsedBase64Key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
console.log("encryptedData = " + encryptedData);
}
{
// Decryption process
var encryptedCipherText = 'U2WvSc8oTur1KkrB6VGNDmA3XxJb9cC+T9RnqT4kD90=’; // or encryptedData;
var decryptedData = CryptoJS.AES.decrypt(encryptedCipherText, parsedBase64Key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
// console.log( "DecryptedData = " + decryptedData );
// this is the decrypted data as a string
var decryptedText = decryptedData.toString(CryptoJS.enc.Utf8);
console.log("DecryptedText = " + decryptedText);
}
</script>
</body>
</html>

Related

How to Encrypt/Decrypt data in Angular and Java - CryptoJS

I found this code
package com.sumant.springboot.learning.springcloudgateway;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class EncryptDecryptHelper {
private static final String SECRET_KEY = "Thisisatestkeyfortesting";
private static SecretKeySpec secretKey;
private static byte[] key;
public static String encrypt(String strToEncrypt){
return encrypt(strToEncrypt, SECRET_KEY);
}
public static String decrypt(String strToDecrypt){
return decrypt(strToDecrypt, SECRET_KEY);
}
public static void setKey(String myKey)
{
MessageDigest sha = null;
try {
key = myKey.getBytes("UTF-8");
sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
// System.out.println(key);
key = Arrays.copyOf(key, 16);
secretKey = new SecretKeySpec(key, "AES");
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
public static String encrypt(String strToEncrypt, String secret)
{
try
{
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
}
catch (Exception e)
{
System.out.println("Error while encrypting: " + e.toString());
}
return null;
}
public static String decrypt(String strToDecrypt, String secret)
{
try
{
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
}
catch (Exception e)
{
System.out.println("Error while decrypting: " + e.toString());
}
return null;
}
public static void main(String[] args) {
String key = "Thisisatestkeyfortesting";
//language=JSON
String data = "{\"title\": \"TestTitle1\",\"author\": \"TestAuthor1\"}";
System.out.println("Original String: " + data);
String encryptedString = EncryptDecryptHelper.encrypt(data, key);
System.out.println("Encrypted String: " + encryptedString);
String decryptedString = EncryptDecryptHelper.decrypt(encryptedString, key);
System.out.println("Decrypted String: " + decryptedString);
}
}
This generates encryption string
Encrypted String:
Qua63XoZnGDpvBYtmoEZipALDamRw6EvmB0oWLD+wgi80PzmMZw2WTX4CIP6R79+
How can I encrypt/decrypt in angular using crypto-js
The code to encrypt on angular side (using encrypt on both sides to confirm settings are ok)
public message: string= "{\"title\": \"TestTitle1\",\"author\": \"TestAuthor1\"}";
public password: string ="Thisisatestkeyfortesting";
public decryptedMessage: string;
const key = CryptoJS.enc.Utf8.parse(this.password);
const iv = CryptoJS.enc.Utf8.parse(this.password);
const encrypted = CryptoJS.AES.encrypt(this.message, key, {
keySize: 16,
iv: iv,
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
console.log('Encrypted :' + encrypted);
Encrypted
:peUrphsVZzpQbi5GF8JWgQ3mWY0tGCE5m9VHM/dYibizS37hUarfHzoFXrKbJZsv
What is wrong in the above code ? why the encrypted text are different? Please suggest the fix
Main goal is to encrypt on angular and decrypt on java/spring , and vise versa

Encrypting and Decrypting password in java

Im Trying to do my homework to create a class called Password that implements the Encryptable interface.
Im trying using RSA Algorythm.
I use some RSA code references from the Google and resulting my code below.
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Key;
import java.util.Arrays;
import javax.crypto.Cipher;
import java.util.Scanner;
public class Password
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String password = sc.nextLine();
KeyPair keyPair = RSAKeyPair.keyPairRSA();
Key publicKey = keyPair.getPublic();
Key privateKey = keyPair.getPrivate();
System.out.println("Original: " + password);
byte[] encrypted = RSAEncryptDecrypt.encrypt(password, privateKey);
System.out.println("Encrypted: " + new String(encrypted));
byte[] decrypted = RSAEncryptDecrypt.decrypt(encrypted, publicKey);
System.out.println("Decrypted: " + new String(decrypted));
}
}
final class RSAConstants {
private RSAConstants() {
}
public static final String ALGORITHM = "RSA";
public static final int ALGORITHM_BITS = 2048;
}
class RSAKeyPair {
public static KeyPair keyPairRSA() {
KeyPairGenerator generator = null;
try {
generator = KeyPairGenerator.getInstance(RSAConstants.ALGORITHM);
} catch (Exception e) {
e.printStackTrace();
}
if (generator != null) {
generator.initialize(RSAConstants.ALGORITHM_BITS);
KeyPair keyPair = generator.genKeyPair();
return keyPair;
}
return null;
}
}
class RSAEncryptDecrypt {
public static byte[] encrypt(String original, Key privateKey) {
if (original != null && privateKey != null) {
byte[] bs = original.getBytes();
byte[] encData = convert(bs, privateKey, Cipher.ENCRYPT_MODE);
return encData;
}
return null;
}
public static byte[] decrypt(byte[] encrypted, Key publicKey) {
if (encrypted != null && publicKey != null) {
byte[] decData = convert(encrypted, publicKey, Cipher.DECRYPT_MODE);
return decData;
}
return null;
}
private static byte[] convert(byte[] data, Key key, int mode) {
try {
Cipher cipher = Cipher.getInstance(RSAConstants.ALGORITHM);
cipher.init(mode, key);
byte[] newData = cipher.doFinal(data);
return newData;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
My Input is:
InterstellarGalactica
All goes smooth except for the result of Encrypted Password
Resulting below
Original: InterstellarGalactica
Encrypted: Sªë/H?ù,X?U4??A???ìñáQ
÷? *?7*??d?'å?Ñ¡w °??? Pè???«{?D÷??cB???'É »???qªîÉDë??~hb??z8?çÿ?hí?{mè?{*îèGê??WÅ{x??ï.5¼?úü;e??G?-F?shèn?FI
áh`UƒIàB!?åäô+D<&"?)?????ß!??3ä?¬???â???<?¬Ü?{ #ó12B?òt?ƒòÆr²Ä·oHQ?ë?«ú?°?î??Äy?:X^<?
&:ryb\?¼
Decrypted: InterstellarGalactica
Why do it is became a meaningless character?
Is there anything wrong with my code?
Can you explain how to do it in proper way(if there is)?
Thanks in advance.
You are using RSA in the wrong way:
In RSA you use the public key for encryption and the private key for decryption.
You however use the private key for encryption and the public key for decryption:
byte[] encrypted = RSAEncryptDecrypt.encrypt(password, privateKey);
byte[] decrypted = RSAEncryptDecrypt.decrypt(encrypted, publicKey);
Additionally please never convert a byte[] that contains binary data to String. If you want to print binary data convert it for example to a hexadecimal or base64 String instead. Or if you want to print it as a number use BigInteger.
// output Base64 encoded
System.out.println(java.util.Base64.getEncoder().encode(encrypted));
// out hexadecimal (uses Apache commons codec library
System.out.println(org.apache.commons.codec.binary.Hex.encodeHexString(encrypted));
// out hexadecimal without external library)
System.out.println(new java.math.BigInteger(1, encrypted).toString(16))
// Output as large number (useful for manual RSA calculations)
System.out.println(new java.math.BigInteger(1, encrypted));

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 (####&&&&&)

AES 256 32 bytes key Encrypt/Decrypt Java [duplicate]

This question already has answers here:
Java Security: Illegal key size or default parameters?
(19 answers)
Closed 6 years ago.
I need to Encrypt XML message (it comes as String) using AES 256 with 32 bytes key. I have tried the following (from http://aesencryption.net/) :
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
/**
Aes encryption
*/
public class AES
{
private static SecretKeySpec secretKey ;
private static byte[] key ;
private static String decryptedString;
private static String encryptedString;
public static void setKey(String myKey){
MessageDigest sha = null;
try {
key = myKey.getBytes("UTF-8");
System.out.println(key.length);
sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit
System.out.println(key.length);
System.out.println(new String(key,"UTF-8"));
secretKey = new SecretKeySpec(key, "AES");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String getDecryptedString() {
return decryptedString;
}
public static void setDecryptedString(String decryptedString) {
AES.decryptedString = decryptedString;
}
public static String getEncryptedString() {
return encryptedString;
}
public static void setEncryptedString(String encryptedString) {
AES.encryptedString = encryptedString;
}
public static String encrypt(String strToEncrypt)
{
try
{
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
setEncryptedString(Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))));
}
catch (Exception e)
{
System.out.println("Error while encrypting: "+e.toString());
}
return null;
}
public static String decrypt(String strToDecrypt)
{
try
{
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
setDecryptedString(new String(cipher.doFinal(Base64.decodeBase64(strToDecrypt))));
}
catch (Exception e)
{
System.out.println("Error while decrypting: "+e.toString());
}
return null;
}
public static void main(String args[])
{
final String strToEncrypt = "My text to encrypt";
final String strPssword = "C0BAE23DF8B51807B3E17D21925FADF273A70181E1D81B8EDE6C76A5C1F1716E";
AES.setKey(strPssword);
AES.encrypt(strToEncrypt.trim());
System.out.println("String to Encrypt: " + strToEncrypt);
System.out.println("Encrypted: " + AES.getEncryptedString());
final String strToDecrypt = AES.getEncryptedString();
AES.decrypt(strToDecrypt.trim());
System.out.println("String To Decrypt : " + strToDecrypt);
System.out.println("Decrypted : " + AES.getDecryptedString());
}
}
I tried to change key array lenght from 16 to 32 and used a larger input String
(I think that's 32 lenght key) but that doesn't work.
key = Arrays.copyOf(key, 32);
Message to encrypt will be as simple as:
<Estructure>
<General>GENERAL DATA</General>
</Estructure>
<Datos>
<DATE>20140606</DATE>
</Datos>
When I run that I get the following Exception:
Error while encrypting: java.security.InvalidKeyException: Illegal key size or default parameters
It works perfectly when using 16 byte Lenght key. How can I make it work with 32 bytes?
By default anything above 128 bit encryption is disabled in the JVM, because Oracle is operating under US jurisdiction.
If you want more than 128 bit encryption you have to download Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download and put the jar files in your JRE/JDK

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;

Categories