Android Base64 Encoding and Apache codec decoding - java

We are using following method for encoding a string using ANDROID Base64.NO_CLOSE
public static String encrypt(String inputString, byte[] keyBytes) {
Calendar cal = Calendar.getInstance();
int mDay = cal.get(Calendar.DAY_OF_MONTH);
// System.out.println("Day of month :::" + mDay);
String encryptedString = "";
Key publicKey = null;
try {
Random generator = new Random(mDay);
int num = (generator.nextInt()) % 100;
String salt = "WEER563784" + num;
inputString += salt;
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(publicKeySpec);
} catch (Exception e) {
System.out.println("Exception rsaEncrypt::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
// Encode the original data with RSA public key
byte[] encodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA");
c.init(Cipher.ENCRYPT_MODE, publicKey);
encodedBytes = c.doFinal(inputString.getBytes());
encryptedString = Base64.encodeToString(encodedBytes,
Base64.NO_CLOSE);
System.out.println(encryptedString);
} catch (Exception e) {
System.out.println("Exception rsaEncrypt::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
return encryptedString;
}
The generated encrypted string is being decrypted outside Android app using following method
public static String decrypt(String inputString, byte[] keyBytes) {
String resultStr = null;
Calendar cal = Calendar.getInstance();
int mDay = cal.get(Calendar.DAY_OF_MONTH);
Random generator = new Random(mDay);
int num = (generator.nextInt()) % 100;
String salt = "qqq" + num;
PrivateKey privateKey = null;
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyBytes);
privateKey = keyFactory.generatePrivate(privateKeySpec);
} catch (Exception e) {
System.out.println("Exception privateKey::::::::::::::::: "
+ e.getMessage());
}
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
// Cipher c = Cipher.getInstance("RSA");
c.init(Cipher.DECRYPT_MODE, privateKey);
// decodedBytes = c.doFinal(Base64.decodeBase64(inputString));
decodedBytes = c.doFinal(Base64InputStream());
} catch (Exception e) {
System.out.println("Exception privateKey1::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
if (decodedBytes != null) {
resultStr = new String(decodedBytes);
System.out.println("resultStr:::" + resultStr + ":::::");
resultStr = resultStr.replace(salt, "");
}
return resultStr;
}
We are getting following exceptions
javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:365)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:391)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
at RSAEncryption.decrypt(RSAEncryption.java:41)
at RSAEncryption.main(RSAEncryption.java:108)
So the questions are
1) Is it possible to decrypt the encrypted string using ANDROID Base64.NO_CLOSE, outside Android, i mean directly in the IDE?
2) In one of post I found that string encrypted using ANDROID Base64.NO_WRAP can be decrypted outside Android env, is this a correct understanding?
Thanks a lot for you your help in advance.
Regards,
Amit

The issue is fixed...
while decrypting we need to use RSA/ECB/NoPadding
Basically when we encrypted the value using RSA in Android device decryption in a separate standalone Java env should use RSA/ECB/NoPadding in the Cipher.
Android Encryption Code:
public static String encrypt(String inputString, byte[] keyBytes) {
Calendar cal = Calendar.getInstance();
int mDay = cal.get(Calendar.DAY_OF_MONTH);
// System.out.println("Day of month :::" + mDay);
String encryptedString = "";
Key publicKey = null;
try {
Random generator = new Random(mDay);
int num = (generator.nextInt()) % 100;
String salt = "MNSadm563784" + num;
//inputString += salt;
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(publicKeySpec);
} catch (Exception e) {
System.out.println("Exception rsaEncrypt::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
// Encode the original data with RSA public key
byte[] encodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA");
c.init(Cipher.ENCRYPT_MODE, publicKey);
encodedBytes = c.doFinal(inputString.getBytes());
encryptedString = Base64.encodeToString(encodedBytes,
Base64.NO_CLOSE);
System.out.print("-----??"+encryptedString+"??-------");
} catch (Exception e) {
System.out.println("Exception rsaEncrypt::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
return encryptedString;
}
Server Decryption code:
public static String decrypt(String inputString, byte[] keyBytes) {
String resultStr = null;
// Calendar cal = Calendar.getInstance();
// int mDay = cal.get(Calendar.DAY_OF_MONTH);
// Random generator = new Random(mDay);
// int num = (generator.nextInt()) % 100;
// String salt = "MNSadm563784" + num;
PrivateKey privateKey = null;
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
keyBytes);
privateKey = keyFactory.generatePrivate(privateKeySpec);
} catch (Exception e) {
System.out.println("Exception privateKey::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
// Cipher c = Cipher.getInstance("RSA");
c.init(Cipher.DECRYPT_MODE, privateKey);
decodedBytes = c.doFinal(Base64.decodeBase64(inputString));
// decodedBytes = c.doFinal(Base64InputStream());
} catch (Exception e) {
System.out.println("Exception privateKey1::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
if (decodedBytes != null) {
resultStr = new String(decodedBytes);
System.out.println("resultStr:::" + resultStr + ":::::");
// resultStr = resultStr.replace(salt, "");
}
return resultStr;
}

Related

Can I have equivalent dot net code from the java code

I have one java code that needs to be converted to c# code.
Java Util class
public class EncryptorDecryptorUtil {
private int keySize;
private Cipher cipher;
public EncryptorDecryptorUtil(int keySize)
{
this.keySize = keySize;
try
{
this.cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (NoSuchPaddingException e)
{
e.printStackTrace();
}
}
public String decrypt(String salt, String iv, String passphrase, String EncryptedText)
{
String decryptedValue = null;
try
{
byte[] saltBytes = hexStringToByteArray(salt);
SecretKeySpec sKey = (SecretKeySpec)generateKeyFromPassword(
passphrase, saltBytes);
byte[] ivBytes = hexStringToByteArray(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
this.cipher.init(2, sKey, ivParameterSpec);
byte[] decordedValue = new BASE64Decoder()
.decodeBuffer(EncryptedText);
byte[] decValue = this.cipher.doFinal(decordedValue);
decryptedValue = new String(decValue);
}
catch (Exception e)
{
e.printStackTrace();
}
return decryptedValue;
}
public static SecretKey generateKeyFromPassword(String password, byte[] saltBytes)
throws GeneralSecurityException
{
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes,
100, 128);
SecretKeyFactory keyFactory =
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
SecretKey secretKey = keyFactory.generateSecret(keySpec);
return new SecretKeySpec(secretKey.getEncoded(), "AES");
}
public static byte[] hexStringToByteArray(String s)
{
System.out.println("s:::::::"+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;
}
}
Java Main methods
public class EncryptionDecryption {
#SuppressWarnings("unchecked")
public static void main(String[] args) {
JSONObject json = new JSONObject();
json.put("applicationNo","PNB00000000000004016");
json.put("custID","PNB000000004016");
String input = json.toJSONString();
String password = "46ea428a97ba4c3094fc66e112d1d678";
EncryptionDecryption enc = new EncryptionDecryption();
String encryptMessage= enc.encryptMessage(input, password);
System.out.println("Encrypted Message :"+encryptMessage);
String encrypt2Message = "8b7a1e90d701f55c49e22135eed31c94 89f9af1e83e8c83bdf603f5428ba6f14 0R2A2JDkY8tFR1FZojY7Su9CVI9zjw4yjr/lRElwU75MF5e0LxgOb+Y/DOyVFNd89Ra4YADIZdopLZ5a59Z2BgEjMpSn27tqnGfFvWtfm+eh+A/aVcB2YwfD9rdsd67x6xUb8kmfL7qnO/uxaHyQtqlvwpNRBVjyfRlk1wPfaxyOQa0oEiWRmUXYxEoJ651EhYtHeHKmII7qzDgcioIYUlsBgZUjOu0sNEdiwSvvHbw=";
String decryptMessage = enc.decryptMessage(encrypt2Message, password);
System.out.println("decryptMessage Message :"+decryptMessage);
}
public String encryptMessage(String txtToEncrypt, String passphrase)
{
System.out.println("encryptMessage :txtToEncrypt :"+txtToEncrypt);
String combineData = "";
try
{
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
String saltHex = getRandomHexString(32);
String ivHex = getRandomHexString(32);
byte[] salt = hexStringToByteArray(saltHex);
byte[] iv = hexStringToByteArray(ivHex);
SecretKeySpec sKey = (SecretKeySpec)generateKeyFromPassword(
passphrase, salt);
cipher.init(1, sKey, new IvParameterSpec(iv));
byte[] utf8 = txtToEncrypt.getBytes("UTF-8");
byte[] enc = cipher.doFinal(utf8);
combineData = saltHex + " " + ivHex + " " +
new BASE64Encoder().encode(enc);
}
catch (Exception e)
{
e.printStackTrace();
}
combineData = combineData.replaceAll("\n", "").replaceAll("\t", "").replaceAll("\r", "");
return combineData;
}
public String decryptMessage(String str, String myKey)
{
String decrypted = null;
try
{
if ((str != null) && (str.contains(" ")))
{
String salt = str.split(" ")[0];
String iv = str.split(" ")[1];
String encryptedText = str.split(" ")[2];
EncryptorDecryptorUtil dec = new EncryptorDecryptorUtil(128);
decrypted = dec.decrypt(salt, iv, myKey, encryptedText);
}
else
{
decrypted = str;
}
}
catch (Exception e)
{
e.printStackTrace();
}
return decrypted;
}
public static String getRandomHexString(int numchars)
{
Random r = new Random();
StringBuilder sb = new StringBuilder();
while (sb.length() < numchars) {
sb.append(Integer.toHexString(r.nextInt()));
}
return sb.toString().substring(0, numchars);
}
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 SecretKey generateKeyFromPassword(String password, byte[] saltBytes)
throws GeneralSecurityException
{
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes,
100, 128);
SecretKeyFactory keyFactory =
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
SecretKey secretKey = keyFactory.generateSecret(keySpec);
return new SecretKeySpec(secretKey.getEncoded(), "AES");
}
}
I have tried below code in .net
public static byte[] hexStringToByteArray(string hexString)
{
byte[] data = new byte[hexString.Length / 2];
for (int index = 0; index < data.Length; index++)
{
string byteValue = hexString.Substring(index * 2, 2);
data[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
return data;
}
public string generateKey(String password, byte[] saltBytes)
{
int iterations = 100;
var rfc2898 =
new System.Security.Cryptography.Rfc2898DeriveBytes(password, saltBytes, iterations);
byte[] key = rfc2898.GetBytes(16);
String keyB64 = Convert.ToBase64String(key);
return keyB64;
}
Decrypt method in c#
public string DecryptAlter(string salt, string iv, string passphrase, string EncryptedText)
{
string decryptedValue = null;
try
{
byte[] saltBytes = hexStringToByteArray(salt);
string sKey = generateKey(passphrase, saltBytes);
byte[] ivBytes = hexStringToByteArray(iv);
byte[] keyBytes = System.Convert.FromBase64String(sKey);
AesManaged aesCipher = new AesManaged();
aesCipher.IV = ivBytes;
aesCipher.KeySize = 128;
aesCipher.BlockSize = 128;
aesCipher.Mode = CipherMode.ECB;
aesCipher.Padding = PaddingMode.PKCS7;
byte[] b = System.Convert.FromBase64String(EncryptedText);
ICryptoTransform decryptTransform = aesCipher.CreateDecryptor(keyBytes, ivBytes);
byte[] plainText = decryptTransform.TransformFinalBlock(b, 0, b.Length);
var res = System.Text.Encoding.UTF8.GetString(plainText);
return res;
}
catch (Exception e)
{
var k = e.Message;
}
return "";
}
Its not working. Please help me
The Encryption password is “46ea428a97ba4c3094fc66e112d1d678”
Encrypted Text - 4cdf7b17b7db00d7911498dec913d3e4 1e55c4e950b772685ccfdb831c82fede SCQXvM7GeKxP0jLtX5xbuF0WvBC/C81wwxtYNduUe9lVzaYztaJ8ifivjaCBWd7O2zSa+/A+vtFfdSWSnN5+RcjWka42QQl4f+yZ8C1Y/efIsUlDVXBXmSEjSUp/4sflXNz7qg62Ka+atpj0aiG6QvU+T5tnafmsDhx/M3zE+Tg=
Now need to decrypt it.
This is what I got so far to guide you towards a final solution. The encrypted message contains a salt and iv that need to be extracted then used to decrypt the message.
using System;
using System.Globalization;
using System.Security.Cryptography;
public class Program
{
public static void Main()
{
string password = "46ea428a97ba4c3094fc66e112d1d678";
string encrypt2Message = "8b7a1e90d701f55c49e22135eed31c94 89f9af1e83e8c83bdf603f5428ba6f14 0R2A2JDkY8tFR1FZojY7Su9CVI9zjw4yjr/lRElwU75MF5e0LxgOb+Y/DOyVFNd89Ra4YADIZdopLZ5a59Z2BgEjMpSn27tqnGfFvWtfm+eh+A/aVcB2YwfD9rdsd67x6xUb8kmfL7qnO/uxaHyQtqlvwpNRBVjyfRlk1wPfaxyOQa0oEiWRmUXYxEoJ651EhYtHeHKmII7qzDgcioIYUlsBgZUjOu0sNEdiwSvvHbw=";
string[] pieces = encrypt2Message.Split(' ');
string salt = pieces[0];
string iv = pieces[1];
string encmessage = pieces[2];
string decryptMessage = DecryptAlter( salt, iv, password, encmessage);
Console.WriteLine("decryptMessage Message :"+decryptMessage);
}
public static byte[] hexStringToByteArray(string hexString)
{
byte[] data = new byte[hexString.Length / 2];
for (int index = 0; index < data.Length; index++)
{
string byteValue = hexString.Substring(index * 2, 2);
data[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
return data;
}
public static string generateKey(String password, byte[] saltBytes)
{
int iterations = 100;
var rfc2898 =
new System.Security.Cryptography.Rfc2898DeriveBytes(password, saltBytes, iterations);
byte[] key = rfc2898.GetBytes(16);
String keyB64 = Convert.ToBase64String(key);
return keyB64;
}
public static string DecryptAlter(string salt, string iv, string passphrase, string EncryptedText)
{
string decryptedValue = null;
try
{
byte[] saltBytes = hexStringToByteArray(salt);
string sKey = generateKey(passphrase, saltBytes);
byte[] ivBytes = hexStringToByteArray(iv);
byte[] keyBytes = System.Convert.FromBase64String(sKey);
AesManaged aesCipher = new AesManaged();
aesCipher.IV = ivBytes;
aesCipher.KeySize = 128;
aesCipher.BlockSize = 128;
aesCipher.Mode = CipherMode.CBC;
aesCipher.Padding = PaddingMode.PKCS7;
byte[] b = System.Convert.FromBase64String(EncryptedText);
ICryptoTransform decryptTransform = aesCipher.CreateDecryptor(keyBytes, ivBytes);
byte[] plainText = decryptTransform.TransformFinalBlock(b, 0, b.Length);
var res = System.Text.Encoding.UTF8.GetString(plainText);
return res;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
return "";
}
}
public string decryptMessage()
{
string str="some encrypted message";
string myKey = "46ea428a97ba4c3094fc66e112d1d678";
string decrypted = null;
try
{
if ((str != null) && (str.Contains(' ')))
{
string salt = str.Split(' ')[0];
string iv = str.Split(' ')[1];
String encryptedText = str.Split(' ')[2];
decrypted = DecryptAlter(salt, iv, myKey, encryptedText);
return decrypted;
}
else
{
decrypted = str;
return decrypted;
}
}
catch (Exception e)
{
}
return decrypted;
}
public string DecryptAlter(string salt, string iv, string passphrase, string EncryptedText)
{
string decryptedValue = null;
try
{
byte[] saltBytes = hexStringToByteArray(salt);
string sKey = generateKey(passphrase, saltBytes);
byte[] ivBytes = hexStringToByteArray(iv);
byte[] keyBytes = System.Convert.FromBase64String(sKey);
AesManaged aesCipher = new AesManaged();
aesCipher.IV = ivBytes;
aesCipher.KeySize = 128;
aesCipher.BlockSize = 128;
aesCipher.Mode = CipherMode.CBC;
aesCipher.Padding = PaddingMode.PKCS7;
byte[] b = System.Convert.FromBase64String(EncryptedText);
ICryptoTransform decryptTransform = aesCipher.CreateDecryptor(keyBytes, ivBytes);
byte[] plainText = decryptTransform.TransformFinalBlock(b, 0, b.Length);
var res = System.Text.Encoding.UTF8.GetString(plainText);
return res;
}
catch (Exception e)
{
var k = e.Message;
}
return "";
}

what will be the exact code of below vb code in java because i am not getting the same encrypted value

' Encrypts a string using tripple DES
Private Function TripleDESEncrypt(ByVal str As String) As TripleDESEncryptResult
' 3DES Encryption
' Generate KEY/IV pair for your local 3DES encrpytion on xmlCard
' Create a new 3DES CryptoProvider and generate KEY/IV pair for encryption
Dim m_cryptoProvider As New TripleDESCryptoServiceProvider
m_cryptoProvider.GenerateIV()
m_cryptoProvider.GenerateKey()
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream
Dim cryptoStream As CryptoStream = _
New CryptoStream(stream, m_cryptoProvider.CreateEncryptor, _
CryptoStreamMode.Write)
Dim Input() As Byte = System.Text.Encoding.Default.GetBytes(str)
cryptoStream.Write(Input, 0, Input.Length)
cryptoStream.FlushFinalBlock()
' Convert to base64, so it'll be XML-friendly
Dim encryptedCardString = System.Convert.ToBase64String(stream.ToArray())
cryptoStream.Close()
cryptoStream.Dispose()
Return New TripleDESEncryptResult(encryptedCardString, m_cryptoProvider.Key, m_cryptoProvider.IV)
End Function
Below code is in java for 3DES encryption and decryption. please try with this code. I hope it will help you
private static final String UNICODE_FORMAT = "UTF8";
public static final String DESEDE_ENCRYPTION_SCHEME = "DESede"; //"DESede/ECB/NoPadding";
private KeySpec ks;
private SecretKeyFactory skf;
private Cipher cipher;
byte[] arrayBytes;
private String myEncryptionKey;
private String myEncryptionScheme;
SecretKey key;
public PasswordEncryption_TrippleDES() throws Exception {
myEncryptionKey = "ThisIsSpartaThisIsanilku";
myEncryptionScheme = DESEDE_ENCRYPTION_SCHEME;
arrayBytes = myEncryptionKey.getBytes(UNICODE_FORMAT);
ks = new DESedeKeySpec(arrayBytes);
skf = SecretKeyFactory.getInstance(myEncryptionScheme);
cipher = Cipher.getInstance(myEncryptionScheme);
key = skf.generateSecret(ks);
}
public String encrypt(String unencryptedString) {
String encryptedString = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT);
byte[] encryptedText = cipher.doFinal(plainText);
encryptedString = new String(Base64.encodeBase64(encryptedText));
} catch (Exception e) {
e.printStackTrace();
}
return encryptedString;
}
public String decrypt(String encryptedString) {
String decryptedText=null;
try {
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptedText = Base64.decodeBase64(encryptedString);
byte[] plainText = cipher.doFinal(encryptedText);
decryptedText= new String(plainText);
} catch (Exception e) {
e.printStackTrace();
}
return decryptedText;
}
public static void main(String args []) throws Exception
{
PasswordEncryption_TrippleDES td= new PasswordEncryption_TrippleDES();
String target="data for encyption";
String encrypted=td.encrypt(target);
String decrypted=td.decrypt(encrypted);
System.out.println("String To Encrypt: "+ target);
System.out.println("Encrypted String:" + encrypted);
System.out.println("Decrypted String:" + decrypted);
}

RSA Encryption Encode using Android Decrypt using apache codec Issue

1) I have a private key in a txt file
2) I have written a decrypt method
while running the decrypt method I am getting the below mentioned exception.
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.EncodedKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Calendar;
import java.util.Random;
import javax.crypto.Cipher;
import android.util.Base64;
public static String decrypt(String inputString, byte[] keyBytes) {
String resultStr = null;
Calendar cal = Calendar.getInstance();
int mDay = cal.get(Calendar.DAY_OF_MONTH);
Random generator = new Random(mDay);
int num = (generator.nextInt()) % 100;
String salt = "XXwerr" + num;
PrivateKey privateKey = null;
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyBytes);
privateKey = keyFactory.generatePrivate(privateKeySpec);
} catch (Exception e) {
System.out.println("Exception privateKey::::::::::::::::: "
+ e.getMessage());
}
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA");
//Also tried
// Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
c.init(Cipher.DECRYPT_MODE, privateKey);
decodedBytes = c.doFinal(Base64.decode(inputString, Base64.NO_CLOSE));
} catch (Exception e) {
System.out.println("Exception privateKey1::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
if (decodedBytes != null) {
resultStr = new String(decodedBytes);
System.out.println("resultStr:::" + resultStr + ":::::");
resultStr = resultStr.replace(salt, "");
}
return resultStr;
}
Following is the main method
public static void main(String[] args) {
FileInputStream fileInputStream = null;
File file = new File("/Users/buta1/Downloads/private.txt");
byte[] bFile = new byte[(int) file.length()];
try {
// convert file into array of bytes
fileInputStream = new FileInputStream(file);
fileInputStream.read(bFile);
fileInputStream.close();
// for (int i = 0; i < bFile.length; i++) {
// System.out.println((char)bFile[i]);
// }
decrypt("08F8CFE58F2E707C314F4D7894E0F1", bFile);
System.out.println("Done");
} catch (Exception e) {
e.printStackTrace();
}
}
THE ENCRYPTION METHOD USED IS AS follows USING ANDROID Base64 class
public static String encrypt(String inputString, byte [] keyBytes)
{
Calendar cal = Calendar.getInstance();
int mDay = cal.get(Calendar.DAY_OF_MONTH);
//System.out.println("Day of month :::" + mDay);
String encryptedString = "";
Key publicKey = null;
try {
Random generator = new Random(mDay);
int num = (generator.nextInt() ) % 100;
String salt = "xx"+num;
inputString += salt;
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(publicKeySpec);
} catch (Exception e) {
System.out.println("Exception rsaEncrypt::::::::::::::::: "+
e.getMessage());
}
// Encode the original data with RSA public key
byte[] encodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA");
c.init(Cipher.ENCRYPT_MODE, publicKey);
encodedBytes = c.doFinal(inputString.getBytes());
encryptedString =
Base64.encodeToString(encodedBytes, Base64.NO_CLOSE);
} catch (Exception e) {
System.out.println("Exception rsaEncrypt::::::::::::::::: "+
e.getMessage());
}
return encryptedString;
}
After using commons codec Base 64
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding ");
getting following error
javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:365)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:391)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
at RSAEncryption.decrypt(RSAEncryption.java:41)
at RSAEncryption.main(RSAEncryption.java:108)
I am assuming that you are trying to run Android code from inside your IDE with the android.jar on your classpath (e.g. by using the ADT Plugin in eclipse). Then this looks like "working as intended" (cf. https://code.google.com/p/android/issues/detail?id=33188).
The android.jar only contains stub implementations for all classes, because the intended way would be to run that code inside an emulator.
If you are trying to write code for Android and you find running the code inside an emulator to be too cumbersome, you could try Roboelectric, which basically replaces all those stubs with real implementations and allows you to run the code from inside your IDE.
On the other hand, if you are not trying to write code for Android you can simply replace android.util.Base64 with org.apache.commons.codec.binary.Base64 or java.util.Base64.Decoder (since Java 8).

Unable to encrypt special characters: not multiple of block length

I have an encryption/decryption algorithm and I'm trying to encrypt some special characters to send to the server from android, but it is throwing an exception:
java.lang.Exception: [encrypt] error:0607F08A:digital envelope routines:EVP_EncryptFinal_ex:data not multiple of block length
Normal Latin characters are encrypted/decrypted fine, but special characters aren't.
Here is my code:
public class MCrypt {
private String iv = "fedcba9876543210";//Dummy iv (CHANGE IT!)
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
private String SecretKey = "0123456789abcdef";//Dummy secretKey (CHANGE IT!)
public MCrypt()
{
ivspec = new IvParameterSpec(iv.getBytes());
keyspec = new SecretKeySpec(SecretKey.getBytes(), "AES");
try {
cipher = Cipher.getInstance("AES/CBC/NoPadding");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public byte[] encrypt(String text) throws Exception
{
//if(text == null || text.length() == 0)
// throw new Exception("Empty string");
byte[] encrypted = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(padString(text).getBytes());
} catch (Exception e)
{
throw new Exception("[encrypt] " + e.getMessage());
}
return encrypted;
}
public byte[] decrypt(String code) throws Exception
{
if(code == null || code.length() == 0)
throw new Exception("Empty string");
byte[] decrypted = null;
try {
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
} catch (Exception e)
{
throw new Exception("[decrypt] " + e.getMessage());
}
return decrypted;
}
public static String bytesToHex(byte[] data)
{
if (data==null)
{
return null;
}
int len = data.length;
String str = "";
for (int i=0; i<len; i++) {
if ((data[i]&0xFF)<16)
str = str + "0" + Integer.toHexString(data[i]&0xFF);
else
str = str + Integer.toHexString(data[i]&0xFF);
}
return str;
}
public static byte[] hexToBytes(String str) {
if (str==null) {
return null;
} else if (str.length() < 2) {
return null;
} else {
int len = str.length() / 2;
byte[] buffer = new byte[len];
for (int i=0; i<len; i++) {
buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
}
return buffer;
}
}
private static String padString(String source)
{
char paddingChar = ' ';
int size = 32;
int x = source.length() % size;
int padLength = size - x;
for (int i = 0; i < padLength; i++)
{
source += paddingChar;
}
return source;
}
}
Does anyone know what the problem here is?
Thanks!
Change this line:
cipher = Cipher.getInstance("AES/CBC/NoPadding");
To
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
From this Blog
Change this line :
cipher = Cipher.getInstance("AES/CBC/NoPadding"); //this may be not decrypt full plaintext.
To:
cipher = Cipher.getInstance("AES/ECB/PKCS7Padding"); // use this for descrypt full plain text without lost.

Cipher / 3DES / CFB / Java and PHP

I have a PHP servor which decrypt data in 3DES with the CFB Mode
I encrypt in PHP :
$montant = "500";
$message_crypte = mcrypt_encrypt(MCRYPT_3DES, "N4y1FRDRJ7wn7eJNnWaahCIS", $montant, ,CRYPT_MODE_CFB, "NCNPJDcR");
$montant = base64_encode($message_crypte);
This script in PHP is OK with other system.
And I want to encrypt in Java :
public class CryptData {
private KeySpec keySpec;
private SecretKey key;
private IvParameterSpec iv;
public CryptData(String keyString, String ivString) {
try {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest(Base64
.decodeBase64(keyString.getBytes("ISO-8859-1")));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
//keySpec = new DESedeKeySpec(keyBytes);
keySpec = new DESedeKeySpec(keyString.getBytes());
key = SecretKeyFactory.getInstance("DESede")
.generateSecret(keySpec);
iv = new IvParameterSpec(ivString.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
public String encrypt(String value) {
try {
Cipher ecipher = Cipher.getInstance("DESede/CFB/NoPadding");
//"SunJCE");
ecipher.init(Cipher.ENCRYPT_MODE, key, iv);
if (value == null)
return null;
// Encode the string into bytes using utf-8
byte[] valeur = value.getBytes("ISO-8859-1");
//byte[] utf8 = value.getBytes();
// Encrypt
byte[] enc = ecipher.doFinal(valeur);
// Encode bytes to base64 to get a string
return new String(Base64.encodeBase64(enc), "ISO-8859-1");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
I have not the same result in PHP and in Java
How modify Java treatment to obtain the same result as PHP?
The answer is:
Cipher ecipher = Cipher.getInstance("DESede/CFB8/NoPadding");
I need to use "CFB8"

Categories

Resources