How to convert Java AES ECB Encryption Code to Nodejs - java

I have code in java for encryption
public String encrypt() throws Exception {
String data = "Hello World";
String secretKey = "j3u8ue8xmrhsth59";
byte[] keyValue = secretKey.getBytes();
Key key = new SecretKeySpec(keyValue, "AES");
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(StringUtils.getBytesUtf8(data));
String encryptedValue = Base64.encodeBase64String(encVal);
return encryptedValue;
}
It returns same value ( eg5pK6F867tyDhBdfRkJuA== ) as the tool here
I converted the code to Nodejs (crypto)
var crypto = require('crypto')
encrypt(){
var data = "Hello World"
var cipher = crypto.createCipher('aes-128-ecb','j3u8ue8xmrhsth59')
var crypted = cipher.update(data,'utf-8','base64')
crypted += cipher.final('base64')
return crypted;
}
But this is giving a different value ( POixVcNnBs3c8mwM0lcasQ== )
How to get same value from both?
What am I missing?

Thanks to dave now I am getting same result both for Java and Nodejs/JavaScript
var crypto = require('crypto')
encrypt(){
var data = "Hello World"
var iv = new Buffer(0);
const key = 'j3u8ue8xmrhsth59'
var cipher = crypto.createCipheriv('aes-128-ecb',new Buffer(key),new Buffer(iv))
var crypted = cipher.update(data,'utf-8','base64')
crypted += cipher.final('base64')
return crypted;
}

Related

C# AES Encryption

I trying to implement this same code to encrypt on c# but always i get some different encrypted code :
This is my Java class :
public class AES256 {
private static final String SECRET_KEY = "my_super_secret_key_ho_ho_ho";
private static final String SALT = "ssshhhhhhhhhhh!!!!";
public static String encrypt(String strToEncrypt) {
try {
byte[] iv = "1234567891234567".getBytes("UTF-8");
IvParameterSpec ivspec = new IvParameterSpec(iv);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(SECRET_KEY.toCharArray(), SALT.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);
return Base64.getEncoder()
.encodeToString(cipher.doFinal(strToEncrypt.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
System.out.println("Error while encrypting: " + e.toString());
}
return null;
}
}
How can i implement the same on c#? i usig this as a model -> c# AES Encrypt but the result is diffetent even using the same secret , salt ,interaction hash count
This what i have on c# :
var passPhrase = "my_super_secret_key_ho_ho_ho";
// Initialization Vector (16 bit length)
var iv = "1234567891234567";
// Encrypt & Decrypt (with advanced settings)
var opts = new AESCryptOptions()
{
PasswordHash = AESPasswordHash.SHA1,
PasswordHashIterations = 65536,
PasswordHashSalt = "ssshhhhhhhhhhh!!!!",
PaddingMode = PaddingMode.PKCS7,
MinSaltLength = 4,
MaxSaltLength = 16,
FixedKeySize=256
};
var encryptedText = new AESCrypt(passPhrase, iv, opts).Encrypt(text);
And the encrypt Method, i changed the hash to sha256, the only change made from the implement from gitHub:
PasswordDeriveBytes password = new PasswordDeriveBytes(
passPhrase,
saltValueBytes,
("SHA256"),
Options.PasswordHashIterations);
// Convert key to a byte array adjusting the size from bits to bytes.
keyBytes = password.GetBytes(keySize / 8);

Unable to decrypt node js Text i Java AES-256-GCM getting Tag mismatch

Am able to encrypt and decrypt node and java code individually but when trying to decrypt the node text in java getting Tag mismatch! Am trying to encrypt and decrypt a simple Hello World text here
node js code i have :
const buffer = require('buffer');
const crypto = require('crypto');
// Demo implementation of using `aes-256-gcm` with node.js's `crypto` lib.
const aes256gcm = (key) => {
const ALGO = 'aes-256-gcm';
// encrypt returns base64-encoded ciphertext
const encrypt = (str) => {
// Hint: the `iv` should be unique (but not necessarily random).
// `randomBytes` here are (relatively) slow but convenient for
// demonstration.
const iv = new Buffer(crypto.randomBytes(16), 'utf8');
const cipher = crypto.createCipheriv(ALGO, key, iv);
// Hint: Larger inputs (it's GCM, after all!) should use the stream API
let enc = cipher.update(str, 'utf8', 'base64');
enc += cipher.final('base64');
console.log(enc);
return [enc, iv, cipher.getAuthTag()];
};
// decrypt decodes base64-encoded ciphertext into a utf8-encoded string
const decrypt = (enc, iv, authTag) => {
const decipher = crypto.createDecipheriv(ALGO, key, iv);
decipher.setAuthTag(authTag);
let str = decipher.update(enc, 'base64', 'utf8');
str += decipher.final('utf8');
return str;
};
return {
encrypt,
decrypt,
};
};
const KEY = new Buffer('fTjWnZr4u7x!z%C*F-JaNdRgUkXp2s5v', 'utf8');
const aesCipher = aes256gcm(KEY);
const [encrypted, iv, authTag] = aesCipher.encrypt('Hello World');
const decrypted = aesCipher.decrypt(encrypted, iv, authTag);
console.log(decrypted); // 'hello, world'
And the java code i have :
private final static int GCM_IV_LENGTH = 12;
private final static int GCM_TAG_LENGTH = 16;
private static String decrypt(String encrypted, SecretKey skey) throws Exception {
byte[] decoded = Base64.getDecoder().decode(encrypted);
byte[] iv = Arrays.copyOfRange(decoded, 0, GCM_IV_LENGTH);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec ivSpec = new GCMParameterSpec(GCM_TAG_LENGTH * Byte.SIZE, iv);
cipher.init(Cipher.DECRYPT_MODE, skey, ivSpec);
byte[] ciphertext = cipher.doFinal(decoded, GCM_IV_LENGTH, decoded.length - GCM_IV_LENGTH);
String result = new String(ciphertext, "UTF8");
return result;
}
The main method of the java execution code is
public static void main(String[] args) throws Exception {
String byte_key="fTjWnZr4u7x!z%C*F-JaNdRgUkXp2s5v";
SecretKey key = new SecretKeySpec(byte_key.getBytes(), "AES");
System.out.println("foo "+ decrypt("1cbKXSnEWixxFi0=", key));
}
I think i am missing something here

How to decrypt a cipher text using Java which is encrypted with Rijndael-256 with custom IV?

I have found a source code at stackoverflow on Rinjndael-256 encryption and decryption written in c#. It is using custom IV appending some extra string. Now I need a decryption method on Java platform. I have found some source code; tried to change and test that. Here is the encryption method on c#:
public static string Encrypt(byte[] text, string key)
{
RijndaelManaged aes = new RijndaelManaged();
aes.KeySize = 256;
aes.BlockSize = 256;
aes.Padding = PaddingMode.None;
aes.Mode = CipherMode.CBC;
aes.Key = Encoding.Default.GetBytes(key);
aes.GenerateIV();
string IV = ("-[--IV-[-" + Encoding.Default.GetString(aes.IV));
ICryptoTransform AESEncrypt = aes.CreateEncryptor(aes.Key, aes.IV);
byte[] buffer = text;
return Convert.ToBase64String(Encoding.Default.GetBytes(Encoding.Default.GetString(AESEncrypt.TransformFinalBlock(buffer, 0, buffer.Length)) + IV));
}
The decryption method on java which is not working for me is:
public static String decrypt(byte[] cipherText, String encryptionKey) throws Exception{
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
return new String(cipher.doFinal(cipherText),"UTF-8");
}
Edit 1:
I have implemented the php code for decryption.
function decrypt($text, $pkey)
{
$key = $pkey;
$text = base64_decode($text);
$IV = substr($text, strrpos($text, "-[--IV-[-") + 9);
$text = str_replace("-[--IV-[-" . $IV, "", $text);
return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $IV), "\0");
}
Is there any manual way of implementing Rijndael-256 in Java? As someone said that
There is no support in any of the Sun JCE providers for anything other than Rijndael with the 128-bit blocksize
I don't have an option to use library

.NET equivalent of Java KeyFactory.getInstance "RSA"/"RSA/ECB/PKCS1Padding"

I have the following code,
public static String encrypt(String plainText, String key){
try{
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.decode(key, Base64.DEFAULT)));
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return Base64.encodeToString(cipher.doFinal(plainText.getBytes("UTF-8")),Base64.DEFAULT);
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
I want to convert this to C#. I have tried CryptUtils but it doesn't work https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack.Common/CryptUtils.cs
Sample key,
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ9AMIIBCgKCAQEAoqB1N9kugk4UKYnbh0fcg3qYyYKP0m4B
MjWd05ReeAdj+7JRYDEKO6xthDdVSdRO1/2V+YtY8DnXWnxRaICwu8235s3imZCyqgYnomPWdY+F
K540oTz/zug+9wbrlzt/WQFUU4lPlQbzm/Gjw8XfaCozT0e3bnWQcD7rORCOyuJgwSGgREjTv1ss
pgEaKTMknii9vpGZLeAXwoeIYROhuT4IoIkPDhtY0/UZiCi6v7Ja2dmy53VlWIkcm3rcnSJdvpXr
OgiHvaNABHmeymNycNqd6WUaysBRheluQ86nq/2nZPW0gcvmYt5zbMMYX3yY/n2WtAKeNQBAEW1q
b0s6MwIDAQAB
Possible encryped value,
Y3VTjghDnTrCeG8C/RklKsJ3Y0Mt89sSGGin28E4iQPQvKqeZBws7rBQEZaRamDWftxCkEYZs4Qh
V2l4IVlrawdtRmQlcQh8McrpqP/97Gz8pEDEYnqA7kqBTqZw0Z5o0WsshGSwiAQ9wNSym4xHejkq
zrKxWP8XCMkcT0NlKlRMoqKKICFKZbqWeSQkQM5y9OEcmB6inNNkJCoM1Ip48+cK3cOE6dqXNVrl
sSTZ8WQKwoB3dJmcYqexR3kAvBYdX6ZxEF+2+6b9h8+tc5G7Y5R2eqycyUossdkCcI3fNVhyc72P
axCjZFWZUgfDGCxg1WNhStrH9L8c59P35JKKug==
Since i don't have the private key, i can't decrypt, but at least this produces the right lengthed values.
So try this (you need bouncycastle for reading pem):
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
var keyBytes =
Convert.FromBase64String(
"MIIBI...."); // your key here
AsymmetricKeyParameter asymmetricKeyParameter = PublicKeyFactory.CreateKey(keyBytes);
RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)asymmetricKeyParameter;
RSAParameters rsaParameters = new RSAParameters();
rsaParameters.Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned();
rsaParameters.Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned();
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParameters);
byte[] plaintext = Encoding.UTF8.GetBytes("amount=1&currency=AED");
byte[] ciphertext = rsa.Encrypt(plaintext, false);
string cipherresult = Convert.ToBase64String(ciphertext);

convert php mcrypt_encrypt MCRYPT_3DES to Java

I have code in PHP
$res = strtoupper(bin2hex(mcrypt_encrypt(MCRYPT_3DES, $this->hex2str($key), $this->hex2str($data), MCRYPT_MODE_ECB)));
public function hex2str($data) {
$len = strlen($data);
$res = pack("H" . $len, $data);
return $res;
}
I try to create in java version.
Java code :
private String doEncrypt3DES(String key, String data) throws Exception{
SecretKey secretKey;
byte[] keyValue;
Cipher c;
keyValue = Hex.decodeHex(key.toCharArray());
DESedeKeySpec keySpec = new DESedeKeySpec(keyValue);
secretKey = SecretKeyFactory.getInstance("DESede").generateSecret(keySpec);
// Create the cipher
c = Cipher.getInstance("DESede/ECB/NoPadding");
c.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] text = data.getBytes("utf-8"); // Base64.decodeBase64(data);
byte[] textEncrypt = c.doFinal(text);
String hex = bytesToHex(textEncrypt);
return hex;
}
But they got different result. Can you help me to fix java code?
data : CED0CF172E8AC451B39FC746C5339F29
key : 436C6561724B657944657632536E724D436C6561724B6579
Use hex decode and not utf-8 decode to data.

Categories