Not able to convert SecretKey to bytearray ( java) - java

I'm trying to get the byte array value of the genrated SecretKey, but the result is always null,
This is my code :
mKeyStore = KeyStore.getInstance(ANDROID_KEYSTORE_PROVIDER);
mKeyStore.load(null);
KeyStore.SecretKeyEntry secretKeyEntry = null;
if (!mKeyStore.containsAlias(KEY_ALIAS_AES)) {
KeyGenerator keyGenerator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEYSTORE_PROVIDER);
KeyGenParameterSpec.Builder builder = null;
builder = new KeyGenParameterSpec.Builder(
KEY_ALIAS_AES,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT);
builder.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setKeySize(256);
keyGenerator.init(builder.build());
sKey = keyGenerator.generateKey();
secretKeyEntry = new KeyStore.SecretKeyEntry(sKey);
mKeyStore.setKeyEntry(KEY_ALIAS_AES, secretKeyEntry.getSecretKey().getEncoded(), null);
}
try {
tmpKey = mKeyStore.getKey(KEY_ALIAS_AES, null).getEncoded();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
tmpKey is always null, any help please ?

Related

How to get the decrypted string back from a JTextfield

I have implemented rsa Encryption and Decryption in Java which works totally fine. But my problem is, when I write my encrypted string to a JTextField, I can't get the correct value back out of the JTextField in order to decrypt the message again.
Here is my code, I believe I am doing something wrong at the conversion of my values (byte[] and string):
public static byte[] encrypt(String message, PublicKey pk) {
Cipher cipher= null;
try {
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pk);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
byte[] chiffrat = null;
try {
chiffrat = cipher.doFinal(message.getBytes());
} catch (IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
return chiffrat;
}
public static String decrypt(byte[] chiffrat, PrivateKey sk)
{
byte[] dec = null;
Cipher cipher = null;
try {
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, sk);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
try {
dec = cipher.doFinal(chiffrat);
} catch (IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
return new String(dec);
}
And in my Window class:
Writing encrypted string in my TextField
JButton btnEncrypt = new JButton("Plaintext -> RSA");
btnEncrypt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
txtEncryptionRSA.setText(new String(rsa.encrypt(pwboxEncryptionPlain.getText(), rsa.key.getPublic())));
}
});
This writes d¿Åád6×Ãö† G0|ôw;-3—?Ó^xudC\Ö>Ós`H9ÅóÛ`¥ in my TextField.
Trying to decrypt and write in another TextField:
JButton btnDecrypt = new JButton("RSA -> Plaintext");
btnDecrypt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
byte[] encryptedmsg = txtEncryptionRSA.getText().getBytes();
System.out.println(encryptedmsg);
pwboxEncryptionPlain.setText(rsaClass.decrypt(encryptedmsg, rsa.key.getPrivate()));
}
});
This prints out: [B#abd4af7 and Encryption fails.

javax.crypto.BadPaddingException: Decryption error - Can't decrypt the encrypted public key

Here are my encryption settings
public static final String ALGORITHM = "RSA";
public static final String CIPHER = "RSA/ECB/PKCS1Padding";
public static final String HASH_ALGORITHM = "SHA-256";
public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
public static final int KEY_SIZE = 1048;
Here is my code to encrypt
public byte[] encrypt(byte[] toEncrypt, String keyPath){
int keyLength = KEY_SIZE/8 - 11;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
String toEncryptString = new String(toEncrypt,StandardCharsets.UTF_8);
String[] lines = toEncryptString.split("(?<=\\G.{" + keyLength + "})");
byte[] encryptedData = new byte[0];
try{
inputStream = new ObjectInputStream(new FileInputStream(keyPath));
final PublicKey publicKey = (PublicKey) inputStream.readObject();
final Cipher cipher = Cipher.getInstance(CIPHER);
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
if(toEncrypt.length >= keyLength){
for(String line : lines){
byteArrayOutputStream.write(cipher.doFinal(line.getBytes("UTF-8")));
}
}else{
byteArrayOutputStream.write(cipher.doFinal(toEncrypt));
}
encryptedData = byteArrayOutputStream.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
byte[] cipheredData = base64Encoder(encryptedData);
System.out.println(Arrays.toString(cipheredData));
return cipheredData;
}
Here is my code to decrypt
public byte[] decrypt(byte[] toDecrypt, String keyPath) {
byte[] decypherText = base64Decoder(toDecrypt);
System.out.println(toDecrypt.length);
System.out.println(decypherText.length);
int keyLength = KEY_SIZE/8 - 11;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
String toEncryptString = Arrays.toString(decypherText);
String[] lines = toEncryptString.split("(?<=\\G.{" + keyLength + "})");
byte[] decipheredData = new byte[0];
try{
inputStream = new ObjectInputStream(new FileInputStream(keyPath));
final PrivateKey privateKey = (PrivateKey) inputStream.readObject();
final Cipher cipher = Cipher.getInstance(CIPHER);
cipher.init(Cipher.DECRYPT_MODE,privateKey);
if(decypherText.length >= keyLength){
for(String line : lines){
byteArrayOutputStream.write(cipher.doFinal(line.getBytes("UTF-8")));
}
}else{
byteArrayOutputStream.write(cipher.doFinal(decypherText));
}
decipheredData = byteArrayOutputStream.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
System.out.println(Arrays.toString(decipheredData));
return decipheredData;
}
I'm trying to encrypt a Public Key "A" with the Public Key "B". Encryption is successful, but when I try to decrypt it with the Private Key "B", it gives me that error.
The code looks fine to me, already reviewed it several times, these past 16 hours, already searched through several posts in here, and did not found a suitable answer for my problem.
Also, it already gave me BadPaddingException when decrypting. "Data must not be longer than 131 bytes". However, I'm using a Cipher with padding, so it can only decrypt data with 120 bytes. Why this error, if the Public key ciphered is splitted into blocks of 120 bytes?
Edit: before anyone else says that encrypting a Public Key is a mistery, have in your mind that it's the purpose of the project.. to have a Public Key as an ID and, as such, the need to encrypt so that no one discovers the ID of the user.
Your code doesn't make sense. You're trying to split the ciphertext on a plaintext string. It isn't there. It got removed when you split the string. In any case the data has been encrypted, so searching for a plaintext in it is futile.
You should be base64-decoding, decrypting, reading objects, and then recombining them using "(?<=\\G.{" + keyLength + "})" as a delimiter.
In fact why you're splitting in the first place and then encrypting multiple lines is a mystery.
And why you're serializing is another. Just encrypt the entire thing, without splitting, base64-encode it, and save that. When decrypting, just base64-decode it and decrypt it.
And, finally, why you're encrypting a public key at all is a complete mystery. It's PUBLIC. Not a secret.

Decrypt data in C# which is encrypted in java using RC4 encryption

I have an encrypted file, which is encrypted in java using RC4 Encryption. Below is the code in java.
public class ata {
public static byte[] a(byte[] bArr, String str) {
try {
return ata.a(bArr, str.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
public static byte[] a(byte[] bArr, byte[] bArr2) {
try {
Cipher instance = Cipher.getInstance("RC4");
instance.init(2, new SecretKeySpec(bArr2, "RC4"));
return instance.update(bArr);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
} catch (NoSuchPaddingException e2) {
e2.printStackTrace();
return null;
} catch (InvalidKeyException e3) {
e3.printStackTrace();
return null;
}
}
}
I need to decrypt the file in C# so i need equivalent class of the java code in C#. Is anybody have any idea how to do it ?

javax.crypto.BadPaddingException: Given final block not properly padded when decrypting bytes sent to server

I am creating a secure chat client and server combo that, when finished, will have multiple layers of encryption. However, I don't understand why I am getting this error. I know there are multiple questions out there with many different answers (some so different I don't understand how anyone gets their problem resolved), however I have yet to find one that I can understand enough of to fix this error.
Originally, this actually worked; it sent the key through without a problem. I don't remember changing any part of this code. Maybe someone can tell me what's wrong? I'll mark the line with the error.
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
at secureserver.Server$1.run(Server.java:88)
at java.lang.Thread.run(Unknown Source)
Part of Server that receives key
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec("i15646dont6321wanna".toCharArray(),"ahhalkdjfslk3205jlk3m4ljdfa85l".getBytes("UTF8"),65536,256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey key = new SecretKeySpec(tmp.getEncoded(),"AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, key, ivspec);
byte[] b = new byte[is.available()];
is.read(b);
/* Line 88 */ byte[] dec = cipher.doFinal(b);
SecretKey ck = new SecretKeySpec(dec,"AES");
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, ck, ivspec);
eciphers.put(client, c);
c.init(Cipher.DECRYPT_MODE, ck, ivspec);
dciphers.put(client, c);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Part of the client that sends key to server
public void sendKey(SecretKey k) {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec("i15646dont6321wanna".toCharArray(),"ahhalkdjfslk3205jlk3m4ljdfa85l".getBytes("UTF8"),65536,256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey key = new SecretKeySpec(tmp.getEncoded(),"AES");
Cipher ec = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
ec.init(Cipher.ENCRYPT_MODE, key, ivspec);
byte[] ekey = ec.doFinal(k.getEncoded());
os.write(ekey);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
It's probably your stream handling that causes this:
byte[] b = new byte[is.available()];
is.read(b);
Is not a correct way of handling streams. Try a Java I/O tutorial to understand how to treat streams.
As a side note, for better and more legible exception handling:
try {
// handling Cipher code...
} catch (final IllegalBlockSizeException | BadPaddingException | IOException e) {
// or use your own checked exception
throw new IllegalArgumentException("Invalid ciphertext", e);
} catch (final GeneralSecurityException e) {
throw new IllegalStateException("Cryptographic algorithms not available", e);
}

"javax.crypto.IllegalBlockSizeException" when decrypt data from database

I want to store data (encrypted with DES) and then take the encrypted data from database and present it as a list. But I have a problem. Here is the code.
public void EncryptDemo(){
try {
FileInputStream keyfis = new FileInputStream("mainkey.key");
byte[] encodedKey = new byte[keyfis.available()];
keyfis.read(encodedKey);
keyfis.close();
Key KeyFromFile = new SecretKeySpec(encodedKey, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
String text=txtToEncryptData.getText(), output;
cipher.init(Cipher.ENCRYPT_MODE, KeyFromFile);
DataDemo = cipher.doFinal(text.getBytes());
InsertIntoDataBase();
//I store it as varbinary in database
} catch (FileNotFoundException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchPaddingException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidKeyException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (BadPaddingException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void DecryptDemo(){
try {
FileInputStream keyfis = new FileInputStream("mainkey.key");
byte[] encodedKey = new byte[keyfis.available()];
keyfis.read(encodedKey);
keyfis.close();
Key KeyFromFile = new SecretKeySpec(encodedKey, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, KeyFromFile);
String sql = "{call SelectAll}";
CallableStatement call = conn.prepareCall(sql);
call.execute();
ResultSet result = call.getResultSet();
DefaultListModel model = new DefaultListModel();
while(result.next()){
DataDemo = result.getBytes("TestData");
byte[] plainText = cipher.doFinal(DataDemo);
String after = new String(plainText);
model.addElement(after);
}
lstDecryptResult.setModel(model);
} catch (SQLException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchPaddingException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidKeyException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (BadPaddingException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
The encrypt and storing is allright. But when I take data from database, I get this error when decrypt (at byte[] plainText = cipher.doFinal(DataDemo);)
Jul 19, 2013 11:40:05 AM databaseencryptdecryptdemo.MainGUI DecryptDemo
SEVERE: null
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
Anyone have a solution for this???
You should divide DataDemo variable into 8 byte pieces.
public List<Byte[]> divideInto8(Byte[] bytes) {
int length = bytes.length;
List<Byte[]> returnValues = new ArrayList<Byte[]>();
for (int i = 0; i < length; i = i + 8) {
Byte[] thebytes = new Byte[8];
for (int j = 0; j < 8; j++) {
thebytes[j] = bytes[i * 8 + j];
}
returnValues.add(thebytes);
}
return returnValues;
}
I found the solution. But I think it's not the best.
I changed the type of table DataDemo from varbinary to image and everything became alright. But my data size store in database is heavier (about 4 times) than the oigin data.
But at least I solved my problem.
Does anyone have a better solution? I willing to hear from you.

Categories

Resources