I am using a C# "encrypt" and need a Java "decrypt" method. I need help in java that i can't replicate C# decryption on java and it is not explicit Padding on C# , i don't know what use in java and my key size I think is different but I am not sure. I'm very confused.
know that i need change Java Policy , and did it ! and Change Key size JAVA to 32 bytes.
C#
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Voa.Cross.Util.Extensions;
namespace Voa.Core.Safeties
{
public class Security
{
private readonly string _defaultKey = "sjkdhfjksdhf3444KDFK4nFLFGKdsnjcnj2cmkeKDIK484dmd999sksksksUUddUZ83k030394m49jdjPuWzRk8Zq2PfnpR3YrYWSq2AaUT6meeC3tr36nTVkuudKWbDyPjhUwbwXBzkUhSPKPpSRheR49em4qJWa6YHSCjKX3K93FEMnqXhYauXwjJwbHXfPWTSdxy6ebCBPyAfqk7Uz5nrRddVjZrxWNCMZYG3PbcvPWA34ekdkd454ldnvJKl";
private readonly int _divisionKey = 4;
private readonly byte[] _iv = new byte[16] {0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c};
private byte[] _key;
public Security() => _key = SHA256.Create().ComputeHash(Encoding.ASCII.GetBytes(_defaultKey));
public string Encrypt(string data, string key)
{
if (!string.IsNullOrEmpty(key))
{
CustomKey(key);
}
var encryptor = Aes.Create();
encryptor.Mode = CipherMode.CBC;
// Set key and IV
var aesKey = new byte[32];
Array.Copy(_key, 0, aesKey, 0, 32);
encryptor.Key = aesKey;
encryptor.IV = _iv;
var memoryStream = new MemoryStream();
var aesEncryptor = encryptor.CreateEncryptor();
var cryptoStream = new CryptoStream(memoryStream, aesEncryptor, CryptoStreamMode.Write);
var plainBytes = Encoding.ASCII.GetBytes(data);
cryptoStream.Write(plainBytes, 0, plainBytes.Length);
cryptoStream.FlushFinalBlock();
var cipherBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
var cipherText = Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length);
return cipherText;
}
public string Decrypt(string data, string key)
{
if (!string.IsNullOrEmpty(key))
{
CustomKey(key);
}
var encryptor = Aes.Create();
encryptor.Mode = CipherMode.CBC;
var aesKey = new byte[32];
Array.Copy(_key, 0, aesKey, 0, 32);
encryptor.Key = aesKey;
encryptor.IV = _iv;
var memoryStream = new MemoryStream();
var aesDecryptor = encryptor.CreateDecryptor();
var cryptoStream = new CryptoStream(memoryStream, aesDecryptor, CryptoStreamMode.Write);
var plainText = string.Empty;
try
{
var cipherBytes = Convert.FromBase64String(data);
cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);
cryptoStream.FlushFinalBlock();
var plainBytes = memoryStream.ToArray();
plainText = Encoding.ASCII.GetString(plainBytes, 0, plainBytes.Length);
}
finally
{
memoryStream.Close();
cryptoStream.Close();
}
return plainText;
}
private void CustomKey(string key)
{
var blockSize = key.Length / _divisionKey;
var splitKey = key.CutString(blockSize).ToList();
var splitDefaultKey = _defaultKey.CutString(blockSize).ToList();
var newKey = string.Concat(splitDefaultKey.Intertwine(splitKey).ToList());
_key = SHA256.Create().ComputeHash(Encoding.ASCII.GetBytes(newKey));
}
}
}
JAVA test...
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class SecurityAESEncryption {
private static final String _key = "sjkdhfjksdhf3444KDFK4nFLFGKdsnjcnj2cmkeKDIK484dmd999sksksksUUddUZ83k030394m49jdjPuWzRk8Zq2PfnpR3YrYWSq2AaUT6meeC3tr36nTVkuudKWbDyPjhUwbwXBzkUhSPKPpSRheR49em4qJWa6YHSCjKX3K93FEMnqXhYauXwjJwbHXfPWTSdxy6ebCBPyAfqk7Uz5nrRddVjZrxWNCMZYG3PbcvPWA34ekdkd454ldnvJKl";
private static final char[] initCharArray = new char[] {0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c};
private static final byte[] initVector = SecurityAESEncryption.charToByteArray(initCharArray);
//private static final String initArray = "26dcff00aded7aeec5fe07af4d08223c";
//private static final byte[] ivValue = SecurityAESEncryption.hexStringToByteArray(initArray);
//private static final byte[] key = DigestUtils.sha256(_key.getBytes(StandardCharsets.US_ASCII)).;
private static final byte[] key = SecurityAESEncryption.computeHash(_key);
public static String encrypt(String value) {
try {
System.out.println(key.length);
System.out.println(Base64.decodeBase64(key).length);
byte[] aesKey = new byte[32];
System.arraycopy(key, 0, aesKey, 0, 32);
SecretKeySpec skeySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(initVector);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
return Base64.encodeBase64String(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String decrypt(String encrypted) {
try {
byte[] encryptedBytes = Base64.decodeBase64(encrypted);
System.out.println(key.length);
System.out.println(Base64.decodeBase64(key).length);
byte[] aesKey = new byte[32];
System.arraycopy(key, 0, aesKey, 0, 32);
IvParameterSpec iv = new IvParameterSpec(initVector);
SecretKeySpec skeySpec = new SecretKeySpec(aesKey, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
//byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
byte[] original = cipher.doFinal(encryptedBytes);
return new String(original,StandardCharsets.US_ASCII);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static byte[] charToByteArray(char[] x)
{
final byte[] res = new byte[x.length];
for (int i = 0; i < x.length; i++)
{
res[i] = (byte) x[i];
}
return res;
}
public static byte[] computeHash(String input) {
try {
// Static getInstance method is called with hashing SHA
MessageDigest md = MessageDigest.getInstance("SHA-256");
return md.digest(input.getBytes(StandardCharsets.US_ASCII));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
public static void main(String[] args) {
String originalString = "123456!##";
System.out.println("Original String to encrypt - " + originalString);
String encryptedString = encrypt(originalString);
System.out.println("Encrypted String - " + encryptedString);
String decryptedString = decrypt("Ci10C7ZjUPoEnitdh7QkEw==");
System.out.println("After decryption - " + decryptedString);
}
Your edited Java prog now successfully encrypts the string "123456!##" to this (Base64 encoded) string "LnZV0Vph+eUeJLT2Gst0kw==" using a String as input to a SHA-256 digest, so the real key used for en-/decryption is
(hex) "07c3491eaa6a6289ca91b7b0f290d60688538860b44753f1cf9617977985d2db".
Using this encoded string as input for your decrypt method returns the original string but when using the encoded/encrypted
string "Ci10C7ZjUPoEnitdh7QkEw==" I'm running into this exception:
javax.crypto.BadPaddingException: Given final block not properly padded.
Such issues can arise if a bad key is used during decryption.
Imho this indicates that the key your're using on Java-side is not the same as on C#-side (we don't see the real input
to Encrypt and I don't know what "CustomKey" is doing :-).
Could you please print out
the aeskey and -iv from your C#-Encrypt method directly after you setup them in encryptor-inits and share them here,
that might be usefull for us to help.
public string Encrypt(string data, string key)
...
// Set key and IV
var aesKey = new byte[32];
Array.Copy(_key, 0, aesKey, 0, 32);
encryptor.Key = aesKey;
encryptor.IV = _iv;
==> print aesKey & _iv
...
Related
I referred to the below link
AES Encryption .net to swift,
But, applying the same for ANDROID, I am not able to get the correct AES encryption with version(PBKDF2) conversion for my code. NEED HELP.
public static String Encrypt(String PlainText) throws Exception {
try {
byte[] salt = new byte[] { 0x49, 0x76, 0x61, 0x6E, 0x20, 0x4D,
0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 };
System.out.println("Exception setting up cipher: "+pbkdf2("<keyname>",salt.toString(),1024,128));
Cipher _aesCipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
byte[] keyBytes =pbkdf2("<keyname>",salt.toString(),1024,128).getBytes();
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
byte[] iv ="OFRna73m*aze01xY".getBytes();//pbkdf2("<keyname>",salt.toString(),2,64).getBytes();
IvParameterSpec ivSpec = new IvParameterSpec(iv);
_aesCipher.init(1, keySpec, ivSpec);
byte[] plainText = PlainText.getBytes();
byte[] result = _aesCipher.doFinal(plainText);
return Base64.encodeToString(result, Base64.DEFAULT);//Base64.encode(result,1));
} catch (Exception ex1) {
System.out.println("Exception setting up cipher: "
+ ex1.getMessage() + "\r\n");
ex1.printStackTrace();
return "";
}
}
public static String pbkdf2(String password, String salt, int iterations, int keyLength) throws NoSuchAlgorithmException, InvalidKeySpecException {
char[] chars = password.toCharArray();
PBEKeySpec spec = new PBEKeySpec(chars, salt.getBytes(), iterations, keyLength);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] hash = skf.generateSecret(spec).getEncoded();
return toHex(hash);
}
// Converts byte array to a hexadecimal string
private static String toHex(byte[] array) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < array.length; i++) {
sb.append(Integer.toString((array[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
Please check below code .
I have created Singletone class for the same so that i can access it anywhere in app.
Below Points Should be same like .net or swift
Important Points are IV , SALT and PASSWORD
Please check this too PBKDF2WithHmacSHA1
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
to generate key we used this
KeySpec spec = new PBEKeySpec(password, salt, 2, 256);
Importnant points are (password, salt,iterantion,bytes) this must be same like other platform which you are using with like .net or swift
public class AesBase64Wrapper {
private static String IV = "it should be same like server or other platform";
private static String PASSWORD = "it should be same like server or other platform";
private static String SALT = "it should be same like server or other platform";
private static volatile AesBase64Wrapper sSoleInstance = new AesBase64Wrapper();
//private constructor.
private AesBase64Wrapper() {
}
public static AesBase64Wrapper getInstance() {
return sSoleInstance;
}
// For Encryption
public String encryptAndEncode(String raw) {
try {
Cipher c = getCipher(Cipher.ENCRYPT_MODE);
byte[] encryptedVal = c.doFinal(getBytes(raw));
//String retVal = Base64.encodeToString(encryptedVal, Base64.DEFAULT);
String retVal = Base64.encodeToString(encryptedVal, Base64.NO_WRAP);
return retVal;
}catch (Throwable t) {
throw new RuntimeException(t);
}
}
public String decodeAndDecrypt(String encrypted) throws Exception {
// byte[] decodedValue = Base64.decode(getBytes(encrypted),Base64.DEFAULT);
byte[] decodedValue = Base64.decode(getBytes(encrypted), Base64.NO_WRAP);
Cipher c = getCipher(Cipher.DECRYPT_MODE);
byte[] decValue = c.doFinal(decodedValue);
return new String(decValue);
}
private String getString(byte[] bytes) throws UnsupportedEncodingException {
return new String(bytes, "UTF-8");
}
private byte[] getBytes(String str) throws UnsupportedEncodingException {
return str.getBytes("UTF-8");
}
private Cipher getCipher(int mode) throws Exception {
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = getBytes(IV);
String xyz = String.valueOf(generateKey());
Log.i("generateKey", xyz);
c.init(mode, generateKey(), new IvParameterSpec(iv));
return c;
}
private Key generateKey() throws Exception {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
char[] password = PASSWORD.toCharArray();
byte[] salt = getBytes(SALT);
KeySpec spec = new PBEKeySpec(password, salt, 2, 256);
SecretKey tmp = factory.generateSecret(spec);
byte[] encoded = tmp.getEncoded();
byte b = encoded[1];
Log.e("Secrete Key", String.valueOf(encoded));
return new SecretKeySpec(encoded, "CBC");
}
}
In Activity you can use it like
String EncryptString = AesBase64Wrapper.getInstance().encryptAndEncode("hello");
String DecryptString = AesBase64Wrapper.getInstance().encryptAndEncode(EncryptString);
// You will Get Output in Decrypted String
Help me on Java equivalent of PHP AES Encryption.
I tried with java AES encryption it was working but the below equivalent php code not giving correct encryption decryption with java
I have given php and equivalent java code, but result is not expected one.
PHP code:
function encrypt($plainText)
{
$key='12345678912345671234567891234567'; //size 32
$md5=md5($key);
$plainText='I am plain text';
$secretKey = hextobin($md5);
$initVector = pack("C*", 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f);
$openMode = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '','cbc', '');
$blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, 'cbc');
$plainPad = pkcs5_pad($plainText, $blockSize);
if (mcrypt_generic_init($openMode, $secretKey, $initVector) != -1)
{
$encryptedText = mcrypt_generic($openMode, $plainPad);
mcrypt_generic_deinit($openMode);
}
$data = bin2hex($encryptedText);
return $data;
}
function decrypt($encryptedText)
{
$key='12345678912345671234567891234567';
$md5=md5($key);
$secretKey = hextobin($md5);
$initVector = pack("C*", 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f);
$encryptedText=hextobin($encryptedText);
$openMode = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '','cbc', '');
mcrypt_generic_init($openMode, $secretKey, $initVector);
$decryptedText = mdecrypt_generic($openMode, $encryptedText);
$decryptedText = rtrim($decryptedText, "\0");
mcrypt_generic_deinit($openMode);
return $decryptedText;
}
//*********** Padding Function *********************
function pkcs5_pad ($plainText, $blockSize)
{
$pad = $blockSize - (strlen($plainText) % $blockSize);
return $plainText . str_repeat(chr($pad), $pad);
}
//********** Hexadecimal to Binary function for php 4.0 version ********
function hextobin($hexString)
{
$length = strlen($hexString);
$binString="";
$count=0;
while($count<$length)
{
$subString =substr($hexString,$count,2);
$packedString = pack("H*",$subString);
if ($count==0)
{
$binString=$packedString;
}
else
{
$binString.=$packedString;
}
$count+=2;
}
return $binString;
}
Java code:
public class StatusAES2 {
private static final String key = "12345678912345671234567891234567";
public static void main(String[] args) {
String plainText = "I am plain text";
System.out.println("Original String to encrypt - " + plainText);
String encryptedString = encrypt(plainText);
System.out.println("Encrypted String - " + encryptedString);
String decryptedString = decrypt(encryptedString);
System.out.println("After decryption - " + decryptedString);
}
public static String encrypt(String value) {
try {
byte[] keybytes=key.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(keybytes);
String md5Str=Hex.encodeHexString(thedigest);
IvParameterSpec iv = new IvParameterSpec(new byte[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15});
keybytes=hextobin(md5Str).getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(keybytes, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
String encryptedText=Hex.encodeHexString(encrypted);//bin2hex
return encryptedText;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String decrypt(String encrypted) {
try {
byte[] keybytes=key.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(keybytes);
String md5Str=Hex.encodeHexString(thedigest);
IvParameterSpec iv = new IvParameterSpec(new byte[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15});
keybytes=hextobin(md5Str).getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(keybytes, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(Hex.decodeHex(encrypted.toCharArray()));
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String hextobin(String s) throws DecoderException, UnsupportedEncodingException {
int length=s.length();
int count=0;
String binString="";
while(count<length){
int c=count+2;
String subs=s.substring(count,c);
String packedString="";
byte[] somevar = DatatypeConverter.parseHexBinary(subs);
byte[] bytes = Hex.decodeHex(subs.toCharArray());
packedString=new String(bytes, "UTF-8");
if (count==0){
binString=packedString;
}else {
binString=binString+packedString;
}
count=count+2;
}
return binString;
}
}
Add this dependency.
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
Try this
CBCBlockCipher cbcBlockCipher = new CBCBlockCipher(new AESEngine());
SecureRandom random = new SecureRandom();
KeyParameter key = new KeyParameter(yourSecretKey);
BlockCipherPadding blockCipherPadding = new PKCS7Padding();
PaddedBufferedBlockCipher pbbc = new PaddedBufferedBlockCipher(cbcBlockCipher, blockCipherPadding);
private byte[] processing(byte[] input, boolean encrypt) throws DataLengthException, InvalidCipherTextException {
int blockSize = cbcBlockCipher.getBlockSize();
int inputOffset = 0;
int inputLength = input.length;
int outputOffset = 0;
byte[] initializationVector = new byte[blockSize];
if (encrypt) {
random.nextBytes(initializationVector);
outputOffset += blockSize;
} else {
System.arraycopy(input, 0, initializationVector, 0, blockSize);
inputOffset += blockSize;
inputLength -= blockSize;
}
pbbc.init(encrypt, new ParametersWithIV(key, initializationVector));
byte[] output = new byte[pbbc.getOutputSize(inputLength) + outputOffset];
if (encrypt) {
System.arraycopy(initializationVector, 0, output, 0, blockSize);
}
int outputLength = outputOffset + pbbc.processBytes(input, inputOffset, inputLength, output, outputOffset);
outputLength += pbbc.doFinal(output, outputLength);
return Arrays.copyOf(output, outputLength);
}
We have an application running in .NET for several years. It uses the below c# code for encryption and decryption of password. Now we have another application in Java to consume the same DB for authentication. Tried various ways but could not get an equivalent code in Java for the below encryption and decryption in C#. As there are lot of data encrypted using this logic and stored in DB, will not be able change the C# code. Could someone help with equivalent code in Java? Thanks in Advance.
private string passphrase = "XYZ";
public string EncryptData(string Data)
{
byte[] Results;
var UTF8 = new UTF8Encoding();
var HashProvider = new MD5CryptoServiceProvider();
byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(passphrase));
var TDESAlgorithm = new TripleDESCryptoServiceProvider();
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
byte[] DataToEncrypt = UTF8.GetBytes(Data);
try
{
ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
}
finally
{
TDESAlgorithm.Clear();
HashProvider.Clear();
}
return Convert.ToBase64String(Results);
}
public string DecryptString(string Message)
{
byte[] Results;
var UTF8 = new UTF8Encoding();
var HashProvider = new MD5CryptoServiceProvider();
byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(passphrase));
var TDESAlgorithm = new TripleDESCryptoServiceProvider();
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
byte[] DataToDecrypt = Convert.FromBase64String(Message.Replace(" ", "+"));
try
{
ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length);
}
finally
{
TDESAlgorithm.Clear();
HashProvider.Clear();
}
return UTF8.GetString(Results);
}
Tried Java Code
import java.security.MessageDigest;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class TripleDESTest {
public static void main(String[] args) throws Exception {
String text = "test";
byte[] codedtext = new TripleDESTest().encrypt(text);
String decodedtext = new TripleDESTest().decrypt(codedtext);
System.out.println(codedtext);
System.out.println(decodedtext);
}
public byte[] encrypt(String message) throws Exception {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest("XYZ"
.getBytes("utf-8"));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
final byte[] plainTextBytes = message.getBytes("utf-8");
final byte[] cipherText = cipher.doFinal(plainTextBytes);
// final String encodedCipherText = new sun.misc.BASE64Encoder()
// .encode(cipherText);
return cipherText;
}
public String decrypt(byte[] message) throws Exception {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest("XYZ"
.getBytes("utf-8"));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher decipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
decipher.init(Cipher.DECRYPT_MODE, key, iv);
// final byte[] encData = new
// sun.misc.BASE64Decoder().decodeBuffer(message);
final byte[] plainText = decipher.doFinal(message);
return new String(plainText, "UTF-8");
}
}
It looks like the problem is not finding equivalent code, but to port your C# code to Java, but because of the C# references and .net assemblies used, to use equivalent Java libs that support Triple DES. Have you investigated equivalent Java libs for Triple Des? A quick search found this example:
https://www.example-code.com/java/crypt2_3des.asp
I'm trying to do an Encryption and Decryption in Java Android.
Below is my code for C#, I need to convert it to Java Android. Can someone help me how to do it?
I've been doing this for almost 2 days yet can't find any solutions on how to convert it. I'm newbie in Android.
public static string Encrypt(string toEncrypt)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader();
string key = "KEY";
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
hashmd5.Clear();
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
public static string Decrypt(string cipherString)
{
try
{
byte[] keyArray;
byte[] toEncryptArray = Convert.FromBase64String(cipherString);
string key = "KEY";
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
hashmd5.Clear();
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
return UTF8Encoding.UTF8.GetString(resultArray);
}
catch (Exception)
{
return "Invalid";
}
}
Try This,
package mypackage;
import java.security.MessageDigest;
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.binary.Base64;
public class Main {
public static void main(String[] args) throws Exception {
String text = "neeraj";
String codedtext = new Main().encrypt(text);
String decodedtext = new Main().decrypt(codedtext);
System.out.println(codedtext); // this is a byte array, you'll just see a reference to an array
System.out.println(decodedtext); // This correctly shows "neeraj"
}
public String encrypt(String message) throws Exception {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest("KEY"
.getBytes("utf-8"));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher cipher = Cipher.getInstance("DES/ECB/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
final byte[] plainTextBytes = message.getBytes("utf-8");
final byte[] cipherText = cipher.doFinal(plainTextBytes);
// final String encodedCipherText = new sun.misc.BASE64Encoder()
// .encode(cipherText);
return Base64.encodeBase64String(cipherText);
}
public String decrypt(String input) throws Exception {
byte[] message = Base64.decodeBase64(input);
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest("KEY"
.getBytes("utf-8"));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher decipher = Cipher.getInstance("DES/ECB/PKCS7Padding");
decipher.init(Cipher.DECRYPT_MODE, key, iv);
// final byte[] encData = new
// sun.misc.BASE64Decoder().decodeBuffer(message);
final byte[] plainText = decipher.doFinal(message);
return new String(plainText, "UTF-8");
}
}
Refer to the main function for usage.
I have updated my code. Your C# program gives output as a base64 string. But in java the input of decrypt and output of encrypt is byte array. Convert the byte array to base64 and it will work.
For Base64 operation in java you need the Apache Commons codec.
In java 8 you can use java.util.Base64
.NET code
public String Decrypt(string encryptedString)
{
byte[] toEncryptArray = Convert.FromBase64String(encryptedString)
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
byte[] keyArray = hashmd5.ComputeHash(System.Text.Encoding.Unicode.GetBytes(key));
hashmd5.Clear();
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(
toEncryptArray, 0, toEncryptArray.Length);
}
Java code
public void decryptin(String encryptedText) throws Exception{
byte[] message = Base64.decodeBase64(encryptedText.getBytes("UTF-8"));
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digestOfUsername = md.digest(key.getBytes("UTF-8"));
byte[] keyBytes = Arrays.copyOf(digestOfUsername, 24);
SecretKey key = new SecretKeySpec(keyBytes, "DESede");
Cipher decipher = Cipher.getInstance("DESede/ECB/PKCS5Padding",new SunJCE());
decipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText = decipher.doFinal(message);// BadpaddingException
String decryptedString = new String(plainText);
}
.NET code working fine but java is code is not give the proper output
its giving BadpaddingException : at dofinal() please correct me where i am doing mistake.
Ok, so the problem is that you are converting the encrypted bytes to a hex string (using the asHex method) but are not converting the hex string back to a byte array correctly for decryption. You can't use getBytes.
You can use the following method to convert a hex string to a byte array:
public static byte[] fromHexString(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
and then change your decrypt method to use:
original = decipher.doFinal(fromHexString(message));
finally i got the ans :
public void decrypt(String encryptedText)throws Exception {
byte[] message = new BASE64Decoder().decodeBuffer(encryptedText);
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digestOfPassword = md.digest(kEY.getBytes("UTF-16LE"));
byte[] keyBytes = new byte[24];
System.arraycopy(digestOfPassword, 0, keyBytes, 0, 16);
System.arraycopy(digestOfPassword, 0, keyBytes, 16, 8);
SecretKey key = new SecretKeySpec(keyBytes, "DESede");
Cipher decipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
decipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText = decipher.doFinal(message);
String decryptedString = new String(plainText, UTF);
}