This question already has answers here:
IllegalBlockSizeException when trying to encrypt and decrypt a string with AES
(4 answers)
Closed 6 years ago.
I am trying to encode the passphase into a properties file so that I don't have to type in the passphase to make an SSH connection. But I am facing the following error :
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at com.test.ssh.SSH_Public_Private.deCryptPwd(SSH_Public_Private.java:191)
at com.test.ssh.SSH_Public_Private.checkHostName(SSH_Public_Private.java:227)
at com.test.ssh.SSH_Public_Private.checkHostName(SSH_Public_Private.java:223)
at com.test.ssh.SSH_Public_Private.connectToSSH(SSH_Public_Private.java:64)
at com.test.ssh.SSH_Public_Private.main(SSH_Public_Private.java:124)
My code is as follows:
private String checkHostName(String hostUserName) throws IOException, InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
String deCrypted = null;
FileInputStream is = new FileInputStream(new File("C:\\test\\SSH\\PrivateKey\\keystore.properties"));
Properties properties = new Properties();
properties.load(is);
ssh_Public_Private = new SSH_Public_Private();
boolean isHostNameExist = false;
if (properties.getProperty(hostUserName) == null) {
OutputStream outputStream = new FileOutputStream(
"C:\\test\\SSH\\PrivateKey\\keystore.properties");
String passPhraseStored = new String(enCryptPwd());
properties.setProperty(hostUserName,passPhraseStored );
properties.store(outputStream, null);
outputStream.close();
is.close();
return checkHostName(hostUserName);
}else{
System.out.println(properties.getProperty(hostUserName));
String passPhrase = properties.getProperty(hostUserName);
deCrypted = deCryptPwd(passPhrase); //isHostNameExist = true;
}
return deCrypted;
}
My encryption and decryption piece of code is as follow :
private static String enCryptPwd() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
String decrypted = null;
byte[] encrypted = null;
try {
String text = "";
Scanner sc = new Scanner(System.in);
System.out.println("Enter your passphrase : " );
text = sc.next();
String key = "Bar12345Bar12345"; // 128 bit key
//String key = "AesSEcREtkeyABCD";
// Create key and cipher
Key aesKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
System.out.println(aesKey.getFormat());
Cipher cipher = Cipher.getInstance("AES");
// encrypt the text
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
encrypted = cipher.doFinal(text.getBytes("UTF-8"));
System.err.println(new String(encrypted));
System.err.println(encrypted.length);
} catch (Exception e) {
e.printStackTrace();
}
return new String(encrypted);
}
private static String deCryptPwd(String encrypted) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
String originalString = "";
try {
String key = "Bar12345Bar12345"; // 128 bit key
//String key = "AesSEcREtkeyABCD";
// Create key and cipher
Key aesKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES");
// decrypt the text
cipher.init(Cipher.DECRYPT_MODE, aesKey);
byte[] encryptBytes = new byte[encrypted.length()];
encryptBytes = encrypted.getBytes();
byte[] decrypted = cipher.doFinal(encryptBytes);
originalString = new String(decrypted, "UTF-8");
System.out.println(originalString);
System.err.println(decrypted);
} catch (Exception e) {
e.printStackTrace();
}
return originalString;
}
I have been trying to read up and I have tried many other ways by including no padding Algorithms as well. My code writes the output into a property file as :
abced=Y\u201Eh\uFFFD\u00EC-:\u00F9\u00F8mC\u0160\u0002\u00F3#\u00DE
My console outputs are :
Enter your passphrase :
abc!##
After encryption >> Y„h?ì-:ùømCŠó#Þ
16
Read from property file >> Y„h?ì-:ùømCŠó#Þ
Generate key using KeyGenerator
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128, new SecureRandom());
SecretKeySpec aesKey = new SecretKeySpec(kg.generateKey().getEncoded(), "AES");
Use AES/CBC/PKCS5Padding to get cipher instance.
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
This should work.
Related
I got an error Input length must be multiple of 16 when decrypting with padded cipher when trying to decrypt my encrypted message.
What I encrypt is this:
{
"guid": "d123-231s-2314w123-21312-2312312",
"userid": "000123",
"channel": "TESTINGCHANNELTEST"
}
but when I decrypt it I got that error. But when I decrypt this message
{
"guid": "00",
"userid": "00",
"channel": "TEST"
}
It works.
What make this issue?
Heres my code to encrypt and decrypt:
public class EncryptDecryptModel {
private static final String key = "aesEncryptionKey";
private static final String initVector = "encryptionIntVec";
public static String encrypt(String value) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
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 {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
//original = Base64.decodeBase64(encrypted);
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
This is to encrypt:
#PostMapping("/getEncrypt")
public String getEncrypt(#RequestBody OpenMediaModel openMediaModel) throws UnsupportedEncodingException, InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException {
EncryptDecryptModel encryptDecryptModel=new EncryptDecryptModel();
MessageDigest digest = MessageDigest.getInstance("SHA-256");
String message = openMediaModel.getGuid() + "|" + openMediaModel.getCif()
+ "|" + openMediaModel.getChannel();
byte[] encodedhash = digest.digest(
message.getBytes(StandardCharsets.UTF_8));
message = message + "|" + new String(encodedhash);
return encryptDecryptModel.encrypt(message);
}
And this is how I decrypt my message:
#GetMapping("/getDecrypt")
public String getDecrypt(#RequestParam String encrypt) throws NoSuchPaddingException, UnsupportedEncodingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeyException {
EncryptDecryptModel encryptDecryptModel=new EncryptDecryptModel();
String plainMessage = encryptDecryptModel.decrypt(encrypt);
String[] splitMessage = plainMessage.split("\\|");
MessageDigest digest = MessageDigest.getInstance("SHA-256");
String message = splitMessage[0] + "|" + splitMessage[1]
+ "|" + splitMessage[2];
//byte[] encodedhash = digest.digest(
// message.getBytes(StandardCharsets.UTF_8));
//return new String(encodedhash).equals(splitMessage[3]);
return splitMessage[0]+"-"+splitMessage[1]+"-"+splitMessage[2];
}
The Issue is when I put long json format like the first one, I got exception:
javax.crypto.IllegalBlockSizeException: Input length must be multiple
of 16 when decrypting with padded cipher
Sorry this is my first time do this encrypt. So got no clue when I decrypt long message. since It work well when I do short message. and I tried use that decodeBase64 but no value
Need help with this.
Thanks in advance.
In order for me to consume a webservice, I need to generate a value for an header named Authorization. The steps to generate the header is as follows:
1. Hash Generation
HashValue = SHA2(username, password, id)
2. Auth Key Generation
Authkey = AES(Salt + anotherId + "=" + HashValue)
These are the algorithms details:
Algorithm - AES
Mode - ECB
Padding - PKCS5Padding
Secret key - someString
Now I will be performing the AES encryption using the above details and the secret key which is a string.
After the encryption, I will use the above generated encrypted value as a header in my rest service call.
I have done this so far:
String username = "username";
String password = "password";
String id = "123456";
String toBeHashed = username + password + id;
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
byte[] hashed = sha256.digest(toBeHashed.getBytes("UTF-8"));
String hashString = "=" + Base64.encodeBase64String(hashed);
System.out.println(hashString);
String salt = "salt";
String anotherId = "123";
byte[] forAuth = (salt + orgId + hashString).getBytes("UTF-8");
//Mocked "secret key". Original key string is of size 16 bytes.
byte[] secKey = "secret key".getBytes("UTF-8");
SecretKey secretKey = new SecretKeySpec(secKey, 0, secKey.length, "AES");
Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
aesCipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] authorizationKey = aesCipher.doFinal(forAuth);
System.out.println("-------------------");
System.out.println("-------------------");
System.out.println(Base64.encodeBase64String(authorizationKey));
But still the backend service says that my authorization key is invalid. Please tell me if I am missing something.
**Encrypt and Decrypt using AES**
public static String encrypt(String value) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
IvParameterSpec iv = new IvParameterSpec("randomStringVec".getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec("randomStringKey".getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(1, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
return Base64.encodeBase64String(encrypted);
}
public static String decrypt(String encrypted) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
IvParameterSpec iv = new IvParameterSpec("randomStringVec".getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec("randomStringKey".getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(2, skeySpec, iv);
byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
return new String(original);
}
**Encryption Using SHA256**
private static String encrypt256(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest crypt = MessageDigest.getInstance("SHA-256");
crypt.reset();
crypt.update(password.getBytes("UTF-8"));
return new BigInteger(1, crypt.digest()).toString(16);
}
You need to change this:
String hashString = "=" + Base64.encodeBase64String(hashed);
System.out.println(hashString);
To:
String hashString = "=" + new String(hashed);
System.out.println(hashString);
Since the hashed key is getting base64encoded before the authorization key generation.
This question already has answers here:
Encrypting and Decrypting String using a Java equilavent of the C# CryptoStream
(7 answers)
Closed 9 years ago.
I need a encrypt/decrypt algorithm for database keys at a java Aplication.
I have to use a algoritmh implement previously using c#, but some classes it use, dont have a java equivalent.
This is the c# code:
public static string Encryptor(string text)
{
SymmetricAlgorithm saEnc;
byte[] dataorg = Encoding.Default.GetBytes(text);
saEnc = SymmetricAlgorithm.Create("RC2");
ICryptoTransform ct = saEnc.CreateEncryptor(Key, Vector);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
cs.Write(dataorg, 0, dataorg.Length);
cs.FlushFinalBlock();
string retorno = Convert.ToBase64String(ms.ToArray());
ms.Close();
saEnc.Clear();
cs.Clear();
cs.Close();
ms = null;
saEnc = null;
cs = null;
return retorno;
}
/**********************************************************************************
DESCRIPCIÓN: Desencripta un texto
PARÁMETROS:
Entrada:
text Texto a desencriptar
Salida:
Texto desencriptado
**********************************************************************************/
public static string Decryptor(string text)
{
SymmetricAlgorithm saDEnc = SymmetricAlgorithm.Create("RC2");
byte[] textoEncriptado = Convert.FromBase64String(text);
MemoryStream ms = new MemoryStream(textoEncriptado);
ICryptoTransform cto = saDEnc.CreateDecryptor(Key, Vector);
MemoryStream mso = new MemoryStream();
CryptoStream cso = new CryptoStream(mso, cto, CryptoStreamMode.Write);
cso.Write(ms.ToArray(), 0, ms.ToArray().Length);
cso.FlushFinalBlock();
string retorno = Encoding.Default.GetString(mso.ToArray());
saDEnc.Clear();
ms.Close();
mso.Close();
cso.Clear();
cso.Close();
saDEnc = null;
ms = null;
mso = null;
cso = null;
return retorno;
}
Some help to create a equivalent code at java? or other alternative?
THanks!
This should do it for you.
public static String encrypt(byte[] key, byte[] iv, String unencrypted) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException,
IllegalBlockSizeException, BadPaddingException{
RC2ParameterSpec ivSpec = new RC2ParameterSpec(key.length*8, iv);
Cipher cipher = Cipher.getInstance("RC2/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "RC2"), ivSpec);
byte[] encrypted = cipher.doFinal(unencrypted.getBytes());
return DatatypeConverter.printBase64Binary(encrypted);
}
public static String decrypt(byte[] key, byte[] iv, String encrypted) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException,
IllegalBlockSizeException, BadPaddingException{
RC2ParameterSpec ivSpec = new RC2ParameterSpec(key.length*8, iv);
Cipher cipher = Cipher.getInstance("RC2/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "RC2"), ivSpec);
byte[] decrypted = cipher.doFinal(DatatypeConverter.parseBase64Binary(encrypted));
return new String(decrypted);
}
Using the same Key and IV (Vector in your code), these methods will produce input/output compatible with the code you've listed.
I'm trying to write a simple program to encrypt and decrypt files using the AES algortihm. I haven't problems with encryption, but decryption..
public static void main(String[] args) throws NoSuchAlgorithmException, FileNotFoundException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
// Инициализация секретных ключей
KeyGenerator keyGenS = KeyGenerator.getInstance("AES");
keyGenS.init(128);
SecretKey sKey1 = keyGenS.generateKey();
SecretKey sKey2 = keyGenS.generateKey();
// Перевод секретных ключей в строку и запись в файл
String key1 = SecretKeyToString(sKey1);
String key2 = SecretKeyToString(sKey2);
spreader.write(fileName1, key1);
spreader.write(fileName2, key2);
spreader.write(fileNameS1, key1);
spreader.write(fileNameS2, key2);
// Чтение секретных ключей из файла и перевод обратно в тип SecretKey
key1 = spreader.read(fileName1);
System.out.println("Секретный ключ 1го пользователя: " +key1);
SecretKey seansKey1=getKeyInstance(key1);
key2 = spreader.read(fileName2);
System.out.println("Секретный ключ 2го пользователя: " +key2);
SecretKey seansKey2=getKeyInstance(key2);
//инициализация и зашифрование сеансового ключа с помощью секретных
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.ENCRYPT_MODE,seansKey1);
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
SecretKey secretKey = keyGen.generateKey();
String stringsecretKey = SecretKeyToString(secretKey);
byte[] byteKey = stringsecretKey.getBytes();
byte[] byteCipherKey1 = aesCipher.doFinal(byteKey);
String encryptedKey = new BASE64Encoder().encode(byteCipherKey1);
System.out.println("Зашифрованный сеансовый ключ с помощью секретного ключа 1: " +encryptedKey);
aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.ENCRYPT_MODE,SeansKey2);
byteKey = etringsecretKey.getBytes();
byte[] byteCipherKey2 = aesCipher.doFinal(byteKey);
encryptedKey = new BASE64Encoder().encode(byteCipherKey2);
System.out.println("Зашифрованный сеансовый ключ с помощью секретного ключа 2: " +encryptedKey);
spreader.write(fileNameEK2, encryptedKey);
//Чтение данных из файла
String text =spreader.read(fileName);
System.out.println(text);
// Зашифрование данных
aesCipher.init(Cipher.ENCRYPT_MODE,secretKey); // константная переменная
byte[] byteText = text.getBytes();
byte[] byteCipherText = aesCipher.doFinal(byteText);
encryptedText = new BASE64Encoder().encode(byteCipherText);
System.out.println("Зашифрованный текст: " +encryptedText);
spreader.write(fileNameOK, encryptedText);
}
Here's the decryption part:
public static void main(String[] args) throws NoSuchAlgorithmException, FileNotFoundException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, UnsupportedEncodingException {
String encryptedText = user.read(fileNameOK);
String key1 = user.read(fileName1);
String key2 = user.read(fileName2);
String encryptedSeanceKey1 = user.read(fileNameEK1);
String encryptedSeanceKey2 = user.read(fileNameEK2);
SecretKey secretKey1=getKeyInstance(key1);
SecretKey secretKey2=getKeyInstance(key2);
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.DECRYPT_MODE,secretKey1,aesCipher.getParameters());
//byte[] byteKey = encryptedSeanceKey1.getBytes();
byte[] byteDecryptedKey = aesCipher.doFinal(encryptedSeanceKey1.getBytes());
String decryptedKey1 = new String(byteDecryptedKey);
System.out.println("Расшифрованный сеансовый ключ с помощью секретного ключа 1: " +decryptedKey1);
aesCipher.init(Cipher.DECRYPT_MODE,secretKey2,aesCipher.getParameters());
byte[] byteKey2 = encryptedSeanceKey2.getBytes();
byteDecryptedKey = aesCipher.doFinal(byteKey2);
String decryptedKey2 = new String(byteDecryptedKey);
System.out.println("Расшифрованный сеансовый ключ с помощью секретного ключа 2: " +decryptedKey2);
// Расшифрование данных
aesCipher.init(Cipher.DECRYPT_MODE,getKeyInstance(decryptedKey1),aesCipher.getParameters());
byte[] byteText = encryptedText.getBytes();
byte[] byteDecryptedText = aesCipher.doFinal(byteText);
decryptedText = new String(byteDecryptedText);
System.out.println(" Расшифрованный текст " +decryptedText);
}
}
Now the problem is the decryption part is: Input length must be multiple of 16 when decrypting with padded cipher
I know that a mistake that I incorrectly keep a session key and bytes are lost. But how I can correctly do it?
There is a little bit of confusion in your code, maybe because some method you called are missing, or maybe because you are using your keys to encrypt...your keys(!!!)
Let's try to encrypt and decrypt the easy way, removing all the stuff that is not strictly needed in your code (like encode your key and save it to a file, and then restore the key without decoding it, etc..).
Let's take a look at the following simplified code based on your:
KeyGenerator keyGenS = KeyGenerator.getInstance("AES");
keyGenS.init(128);
SecretKey sKey1 = keyGenS.generateKey();
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.ENCRYPT_MODE,sKey1);
byte[] byteText = "Insert here whatever you want to crypt".getBytes();
byte[] byteCipherText = aesCipher.doFinal(byteText);
We have generated our key with KeyGenerator, and then we have initialized our Cipher instance with that key. At this point we simply call doFinal() passing the plainText we want to encrypt.
That's all for the encryption part. Of course you can save your keys and byteCipherText to a file if you want, but all the other staff is (at least) useless.
The decryption part is easy as the encryption. The logic is the same.
If you saved your key on a file, just read it into a byte[], and use it for initialize your cipher instance. Something like this:
aesCipher.init(Cipher.DECRYPT_MODE, sKey1);
byte[] plainText = aesCipher.doFinal(byteCipherText);
If you put all the above code into a main() and run it, you should have into plainText the same text as in byteText.
You can verify it with a
System.out.println(new String(plainText));
Try to start from here, then add all other things you may need.
Hope this helps.
Regards
I am trying to simulate asymmetric key system. I use following code to generate key pairs, encrypt, decrypt passwords. I have a distributed environment and for the moment I save the keys generated in a file system. I know that is not secure but its just for testing purposes.
private static SecureRandom random = new SecureRandom();
static {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
}
protected synchronized void generateKeys() throws InvalidKeyException, IllegalBlockSizeException,
BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");
generator.initialize(256, random);
KeyPair pair = generator.generateKeyPair();
Key pubKey = pair.getPublic();
Key privKey = pair.getPrivate();
//store public key
try {
storeKey(pubKey, Constants.KEY_PATH.concat(Constants.SERVER_PREFIX.concat("-publickey")));
} catch (Exception e) {
e.printStackTrace();
DBLogger.logMessage(e.toString(), Status.KEY_GENERATION_ERROR);
}
//store private key
try {
storeKey(privKey, Constants.KEY_PATH.concat(Constants.SERVER_PREFIX.concat("-privatekey")));
} catch (Exception e) {
e.printStackTrace();
DBLogger.logMessage(e.toString(), Status.KEY_GENERATION_ERROR);
}
}
protected synchronized String encryptUsingPublicKey(String plainText) throws IllegalBlockSizeException, BadPaddingException,
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException,
FileNotFoundException, IOException, ClassNotFoundException {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, readKey(Constants.KEY_PATH.concat(Constants.SERVER_PREFIX.concat("-publickey"))), random);
byte[] cipherText = cipher.doFinal(plainText.getBytes());
System.out.println("cipher: " + new String(cipherText));
return new String(cipherText);
}
protected synchronized String decryptUsingPrivatekey(String cipherText) throws NoSuchAlgorithmException,
NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, FileNotFoundException,
IOException, ClassNotFoundException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, readKey(Constants.KEY_PATH.concat(Constants.SERVER_PREFIX.concat("-privatekey"))));
byte[] plainText = cipher.doFinal(cipherText.getBytes());
System.out.println("plain : " + new String(plainText));
return new String(plainText);
}
public static void main(String[] args) {
KeyGenerator keyGenerator = new KeyGenerator();
try {
keyGenerator.deleteAllKeys(Constants.KEY_PATH);
keyGenerator.generateKeys();
String cipherText = keyGenerator.encryptUsingPrivateKey("dilshan");
keyGenerator.decryptUsingPublickey(cipherText);
// String cipherText = keyGenerator.encryptUsingPublicKey("dilshan1");
// keyGenerator.decryptUsingPrivatekey(cipherText);
} catch (Exception e) {
e.printStackTrace();
DBLogger.logMessage(e.toString(), Status.KEY_GENERATION_ERROR);
}
}
This works perfectly well in most of the time. But some times it generates following error. This happens occasionally. Most of the time this works so I have no issue is with the code. I belive this is something to do with the serialization/serialization process to file system. Help is appreciated.
Note : I am using bouncycastle.
Error is as follows,
javax.crypto.BadPaddingException: unknown block type
at org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at com.dilshan.ttp.web.KeyGenerator.decryptUsingPublickey(KeyGenerator.java:105)
at com.dilshan.ttp.web.KeyGenerator.main(KeyGenerator.java:150)
Happens at,
byte[] plainText = cipher.doFinal(cipherText.getBytes());
in decryptUsingPrivatekey method.
The cipher text is binary data. If you convert it to a String using the default encoding it is very likely that you encounter byte sequences that cannot be represented by a character. Thus, during decryption when you convert the String back to a byte array you don't end up with the same bytes and the decryption fails.
To solve that, don't convert the cipher text to a string, instead carry the byte[] around.