I need to encrypt the username and password and encode them and send it via SOAP header.
I used DES algorithm to encrypt the plainText `
String key = "qwer1234qwetr123wqw";
String x = "sadgsagd:%%^%ghsagdh";
byte[] keyBytes = new byte[1024];
byte[] plaintext = x.getBytes();
byte[] tdesKeyData = key.getBytes();
Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
SecretKeySpec myKey = new SecretKeySpec(tdesKeyData, "DESede");
IvParameterSpec ivspec = new IvParameterSpec(keyBytes);
c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
byte[] cipherText = c3des.doFinal(plaintext);
int hash = Base64.encode(cipherText).hashCode();
return Base64.encode(cipherText);`
At runtime i am getting an Exception:
javax.crypto.BadPaddingException: Given
if you are using byte buffer of 64,i probably is too long change it to 32,
or use the length of file like this byte[] buffer = new byte[(int)new File("data").length()];
my problem get solved after doing this..
Related
I have done encryption in android with a static password i.e. "encrypt". The encryption works fine and encrypts the data. But when i try to decrypt the encrypted text it does not show. The code to decrypt is as follow.
public String decrypt(String msg, String inputPassword) throws Exception{
SecretKeySpec key= generateKey(inputPassword);
Cipher c = Cipher.getInstance(AES);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decodedValue= Base64.decode(msg, Base64.DEFAULT);
/*If this line is present the encrypted message is not seen*/
byte[] decValue = c.doFinal(Base64.decode(decodedValue,
Base64.DEFAULT));
String decryptedValue = new String(decodedValue);
String decryptedValue = new String(decValue, StandardCharsets.UTF_8);
return decryptedValue;
}
When the code (below the comment) is enabled. The message is not displayed. But when the line is commented. This is shown in the message box
After the code is commented.
This is the encrypt and key generate methods.
public String encrypt(String message, String inputPassword) throws Exception{
SecretKeySpec key = generateKey(inputPassword);
Cipher c = Cipher.getInstance(AES);
c.init(c.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(message.getBytes());
String encryptedValue = Base64.encodeToString(encVal, Base64.DEFAULT);
return encryptedValue;
}
//For generating key for encryption
public SecretKeySpec generateKey(String inputPassword) throws Exception{
final MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] bytes = inputPassword.getBytes("UTF-8");
digest.update(bytes, 0, bytes.length);
byte[] key = digest.digest();
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
return secretKeySpec;
}
The log is follow
enter image description here
Also the API level is not maintained... I don't know where to setup this as well.
enter image description here
Could you try changing this
String decryptedValue = new String(decodedValue)
to this
String decryptedValue = new String(decodedValue, StandardCharsets.UTF_8)
And for your error, try changing to this
c.doFinal(Base64.decode(decodedValue, Base64.DEFAULT))
I am googling and testing solution for a while and so far no success. There is always some problem with it. Following code is "working" (meaning do not show any error while it is running) on Android Kitkat and higher, but decrypted files are not readable. Why?
final static byte[] iv = new byte[16];//ADDED
final static int buffer = 102400;
final static String encryptionType = "AES/CFB8/NoPadding";//CHANGED TO DIFFERENT TYPE
static void encrypt(String password, File fileInput, File fileOutput) throws Exception {
IvParameterSpec ivParams = new IvParameterSpec(iv);//ADDED
FileInputStream fis = new FileInputStream(fileInput);
FileOutputStream fos = new FileOutputStream(fileOutput);
SecretKeySpec sks = new SecretKeySpec(password.getBytes("UTF-8"), encryptionType);
Cipher cipher = Cipher.getInstance(encryptionType);
//cipher.init(Cipher.ENCRYPT_MODE, sks);REPLACED
cipher.init(Cipher.ENCRYPT_MODE, sks, ivParams);
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
int b;
byte[] d = new byte[buffer];
while ((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
cos.flush();
cos.close();
fis.close();
}
static void decrypt(String password, File fileInput, File fileOutput) throws Exception {
IvParameterSpec ivParams = new IvParameterSpec(iv);//ADDED
FileInputStream fis = new FileInputStream(fileInput);
FileOutputStream fos = new FileOutputStream(fileOutput);
SecretKeySpec sks = new SecretKeySpec(password.getBytes("UTF-8"), encryptionType);
Cipher cipher = Cipher.getInstance(encryptionType);
//cipher.init(Cipher.ENCRYPT_MODE, sks);REPLACED
cipher.init(Cipher.DECRYPT_MODE, sks, ivParams);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[buffer];
while ((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}
EDIT: After I changed type to "AES/CFB8/NoPadding", it seems to be ok, there is no error in process, but decrypted file is not readable.
The problem in the decrypt method is caused by this line:
cipher.init(Cipher.ENCRYPT_MODE, sks);
the mode needs to Cipher.DECRYPT_MODE, so the line should be
cipher.init(Cipher.DECRYPT_MODE, sks);
Other issues are the use of the long obsolete DESede algorithm, the lack of any IV generation and handling, the absence of a good password-based key derivation algorithm, and the lack of any MAC on the ciphertext. Correctly using AES GCM mode with proper nonce generation and handling, and use of PBKDF2 (which is available on Android and Oracle Java) would represent significant improvements.
You don't supply an IV, so one is generated for you automatically. You must find a way to transmit this IV to the recipient. Typically the IV/Nonce is prepending to the ciphertext and stripped off by the recipient in order to decrypt the data. CipherInputStream/CipherOutputStream does not do this for you, so you must do it on your own.
I finally solve this problem by using shorter password. I am not sure why, but on Android 7 and 8, there is no problem with long password, but same password on Android 4.4 leads to crazy errors and brake encryption.
I'm working on a security application using my own customized cryptography method, and having a problem on message decryption.
Here is an my Code
private static void myCryptography(){
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] input = "Hitesh Dhamshaniya".getBytes();
byte[] keyBytes = "ABCD657865BHNKKK".getBytes();
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
// encryption pass
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
Log.e("==> ", " == > Encode " + Base64.encodeToString(cipherText, Base64.DEFAULT));
String encodedStr = Base64.encodeToString(cipherText, Base64.DEFAULT);
// decryption pass
cipherText = Base64.decode(encodedStr, Base64.DEFAULT);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText = new byte[cipher.getOutputSize(ctLength)];
int ptLength = cipher.update(cipherText, 0, ctLength, plainText, 0);
ptLength += cipher.doFinal(plainText, ptLength);
Log.e("==> ", " == > Decoded " + new String(plainText, "UTF-8"));
}
Getting below output
== > Encode TteNmufoa5AWWmEPBmQ3N8fdqRpahvwUR7CSclAcsjM=
== > Decoded Hitesh Dhamshaniya���������������������
How to remove unwanted character like '��' from decode string.
The cipher removes the padding automatically. What you see here comes from the conversion of the byte array plainText to the string. You should only use the first ptLength bytes instead of the whole array:
new String(plainText, 0, ptLength, "UTF-8")
I am working on encrypting (and later decrypting) strings in .Net and Java (on Android), using AES encryption , in the .Net side every thing is OK, in the Android(Java) side the output string of the posted code has unknown symbols.
String stdiv = "1234567890123456";
String txtinput = txtview1.getText().toString();
String mainkey = "0000999988887777";
byte[] key;
key = mainkey.getBytes("UTF8");
byte[] iv = stdiv.getBytes("UTF8");
byte[] input = txtinput.getBytes("UTF8");
Cipher cipher;
cipher = Cipher.getInstance("AES/CBC/PKCS7PADDING");
SecretKeySpec keyspec = new SecretKeySpec(key, "AES" );
IvParameterSpec paramspec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, keyspec, paramspec);
byte[] result = cipher.doFinal(input);
String str=new String(result,"UTF8");
txtview2.setText(str);
I am using code to Base-64 encode and encrypt data in c#, then I ship the file over to my Android app where I attempt to decrypt it.
Problem is, I get an "Length of Base64 encoded input string is not a multiple of 4." error when decrypting:
(Java code for Android):
try
{
Boolean inEvent = false;
// read encrypted file to string
BufferedInputStream fin = new BufferedInputStream(new FileInputStream(filename));
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte buffer[] = new byte[8192];
int read = fin.read(buffer);
while(read != -1) {
bout.write(buffer, 0, read);
read = fin.read(buffer);
}
fin.close();
String encryptedText = bout.toByteArray().toString();
String unencryptedText = "";
// decrypt string
try
{
unencryptedText = Decrypt(encryptedText, sKey); <-- error occurs here
}
catch ( Exception e)
{
alert(e.getMessage());
return sched;
}
Decrypt method:
protected String Decrypt(String text, String key) throws Exception
{
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
byte[] keyBytes= new byte[16];
byte[] b= key.getBytes("UTF-8");
int len= b.length;
if (len > keyBytes.length) len = keyBytes.length;
System.arraycopy(b, 0, keyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.DECRYPT_MODE,keySpec,ivSpec);
byte [] results = cipher.doFinal(Base64Coder.decode(text));
return new String(results,"UTF-8");
}
Finally, here is the c# code I am encrypting with:
(c# code):
string Encrypt(string textToEncrypt, string key)
{
RijndaelManaged rijndaelCipher = new RijndaelManaged();
rijndaelCipher.Mode = CipherMode.CBC;
rijndaelCipher.Padding = PaddingMode.PKCS7;
rijndaelCipher.KeySize = 0x80;
rijndaelCipher.BlockSize = 0x80;
byte[] pwdBytes = Encoding.UTF8.GetBytes(key);
byte[] keyBytes = new byte[0x10];
int len = pwdBytes.Length;
if (len > keyBytes.Length)
{
len = keyBytes.Length;
}
Array.Copy(pwdBytes, keyBytes, len);
rijndaelCipher.Key = keyBytes;
rijndaelCipher.IV = keyBytes;
ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
byte[] plainText = Encoding.UTF8.GetBytes(textToEncrypt);
return Convert.ToBase64String(transform.TransformFinalBlock(plainText, 0, plainText.Length));
}
Not sure what's wrong. Does the length of the key have to be some specific number of bytes long?
The comment has already identified the problem, and you'd see it immediately if you debugged the key item here: the base 64 string you think you are reading.
You collect your bytes from the file in bout. But your attempt to convert it to a string representation is not doing anything like what you imagine. It's going to be something like "[B#2352544e]", just Java's internal default toString() from the array. Instead, try new String(bout.toByteArray(), Charset.forName("US-ASCII")).