Android Unsupported key size: 3 bytes on decrypt text - java

I have simple json object as:
json:
{
"bookInfo": {
"type": "book",
"onvan": "کتاب دو",
"tadvin": "دفتر",
"nasher": "بوستان",
"nobat": "اول",
"shabek": "1100",
"gheymat": "2000 تومان",
"tasvirData": ""
}
}
after encryption that on c# with 123 key, i have this result:
hlAkzlLeVE3JdYrk61dy8901K2tXWqx5qxYd1t8zVSZzx12lD6nxqZRlPRI8yX8PECxaHJ5zdueY0/A0J7Lxxlv2DHvdI/H+Qu2bsQI6X/Qc6ISwlY7Q6c0IiwWtKuFm5f8BC9wNSSqPXkBM7J+hwEtHUBAoh+IMzxNXvnA/hZIp3R2FznX4cdJhs4Lnm003WLGiKwJ1fEgzUl55WKBIh2dMwQwqpTlNmLFIo6ovlJYMt4DTaoeET+VAhHcGtX1u10910EZ1hCqb1pcspE1SPQ==
now when I try to decrypt that with 123 key I get this error:
Unsupported key size: 3 bytes
EncryptUtils class:
public class EncryptUtils {
public static SecretKey generateKey(String mySecret) throws NoSuchAlgorithmException, InvalidKeySpecException {
return new SecretKeySpec(mySecret.getBytes(), "AES");
}
public static byte[] encryptMsg(String message, SecretKey secret)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
Cipher cipher = null;
cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
byte[] cipherText = cipher.doFinal(message.getBytes("UTF-8"));
return cipherText;
}
public static String decryptMsg(byte[] cipherText, SecretKey secret)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidParameterSpecException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
Cipher cipher = null;
cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret);
String decryptString = new String(cipher.doFinal(cipherText), "UTF-8");
return decryptString;
}
}
and this is my decrypt code:
String mySecret="123";
SecretKey secretKey = EncryptUtils.generateKey(mySecret);
JSONObject bookObject = new JSONObject(EncryptUtils.decryptMsg(bookContent.getBytes("UTF-8"), secretKey));

The problem is that the string you are passing in to the hexToBytes function is Base64 encoded, it's not a hex string, so reading the first two characters as an integer causes an exception.
Change the line in decrypt to this:
String decryptString = new String(cipher.doFinal(cipherText), "UTF-8");
To:
String decryptString= cipher.doFinal(Base64.decode(cipherText,Base64.DEFAULT));
Happy coding!!

Related

problem while decrypting private key getting javax.crypto.AEADBadTagException: Tag mismatch! Error

I have been trying to figure this out for 2 days now. Encryption method works fine, but during the decryption tests I am getting the exception below. Especially I am using: AES/GCM/NoPadding.
Error :
Exception in thread "main" javax.crypto.AEADBadTagException: Tag mismatch!
at java.base/com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:623)
at java.base/com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1116)
at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1053)
at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853)
at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2202)
at com.solarwinds.whd.symmetric.GSMTest.decrypt(GSMTest.java:72)
at com.solarwinds.whd.symmetric.GSMTest.main(GSMTest.java:38)
Code:
import javax.crypto.*;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import static java.nio.charset.StandardCharsets.UTF_8;
public class GSMTest {
private static final String ALGORITHM = "AES";
private static final int T_LEN = 128;
private static final int IV_LENGTH = 12;
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, UnsupportedEncodingException, InvalidKeyException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException {
String s = "xaT2UtvzIt2rO8OMxaT2UtvzIt2rO8OM";
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256);
SecretKey key = keyGenerator.generateKey();
GSMTest ob = new GSMTest();
System.out.println("Before encrypt: "+s);
String se = ob.encrypt(s, key);
System.out.println("After encrypt: "+se);
String sd = ob.decrypt(se, key);
System.out.println("After decrypt: "+sd);
}
public String encrypt(String text, SecretKey key) throws UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException {
byte[] iv = new byte[IV_LENGTH];
(new SecureRandom()).nextBytes(iv);
SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), ALGORITHM);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec ivSpec = new GCMParameterSpec(T_LEN, iv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] ciphertext = cipher.doFinal(text.getBytes(UTF_8));
byte[] encrypted = new byte[iv.length + ciphertext.length];
System.arraycopy(iv, 0, encrypted, 0, iv.length);
System.arraycopy(ciphertext, 0, encrypted, iv.length, ciphertext.length);
Base64.Encoder en = Base64.getEncoder();
return en.encodeToString(encrypted);
}
public String decrypt(String encryptedText, SecretKey key) throws IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException {
Base64.Decoder de = Base64.getDecoder();
byte[] decoded = de.decode(encryptedText);
byte[] iv = Arrays.copyOfRange(decoded, IV_LENGTH, decoded.length);
SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), ALGORITHM);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec ivSpec = new GCMParameterSpec(T_LEN, iv);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] decryptedText = cipher.doFinal(decoded);
return new String(decryptedText);
}
}
Can anyone help? I have been reading many about, and still cannot find anything wrong.

AES Encryption using CBC and PKCS5/7Padding using bouncy castle in java/android

I found this guide for java bouncy castle https://www.bouncycastle.org/fips/BCUserGuide.pdf
I tried to run the following example 3.3.1 AES Encryption using CBC and PKCS5/7Padding:
static byte[] encryptBytes(FipsOutputEncryptor outputEncryptor, byte[] plainText) throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
CipherOutputStream encOut = outputEncryptor.getEncryptingStream(bOut);
encOut.update(plainText);
encOut.close();
return bOut.toByteArray();
}
static byte[] decryptBytes(FipsInputDecryptor inputDecryptor,
byte[] cipherText) throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
InputStream encIn = inputDecryptor.getDecryptingStream(
new ByteArrayInputStream(cipherText));
int ch;
while ((ch = encIn.read()) >= 0)
{
bOut.write(ch);
}
return bOut.toByteArray();
}
// 3.3.1 AES Encryption using CBC and PKCS5/7Padding
// ensure a FIPS DRBG in use.
CryptoServicesRegistrar.setSecureRandom(
FipsDRBG.SHA512_HMAC.fromEntropySource(
new BasicEntropySourceProvider(new SecureRandom(), true))
.build(null, true));
byte[] iv = new byte[16];
CryptoServicesRegistrar.getSecureRandom().nextBytes(iv);
FipsSymmetricKeyGenerator<SymmetricSecretKey> keyGen =
new FipsAES.KeyGenerator(128,
CryptoServicesRegistrar.getSecureRandom());
SymmetricSecretKey key = keyGen.generateKey();
FipsSymmetricOperatorFactory<FipsAES.Parameters> fipsSymmetricFactory =
new FipsAES.OperatorFactory();
FipsOutputEncryptor<FipsAES.Parameters> outputEncryptor =
fipsSymmetricFactory.createOutputEncryptor(key,
FipsAES.CBCwithPKCS7.withIV(iv));
byte[] output = encryptBytes(outputEncryptor, new byte[16]);
FipsInputDecryptor<FipsAES.Parameters> inputDecryptor =
fipsSymmetricFactory.createInputDecryptor(key,
FipsAES.CBCwithPKCS7.withIV(iv));
byte[] plain = decryptBytes(inputDecryptor, output);
and the code don't compile.
I added the following libraries to the classpath
bcprov-jdk15on-155.jar
bcmail-jdk15on-155.jar
bcpg-jdk15on-155.jar
bcpkix-jdk15on-155.jar
The reason for I use the library is to integrate the AesCbcPkcs7 with my android application. Can you point me any hint in order to compile the above examples ?
Best Regards,
Aurelian
I tested with the following code - without bouncy castle - and works perfect:
import android.util.Base64;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* Created by aurelian.rosca.
*/
public class EncryptionProvider2 {
private final String characterEncoding = "UTF-8";
private final String cipherTransformation = "AES/CBC/PKCS5Padding";
private final String aesEncryptionAlgorithm = "AES";
public byte[] decrypt(byte[] cipherText, byte[] key, byte [] initialVector) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
{
Cipher cipher = Cipher.getInstance(cipherTransformation);
SecretKeySpec secretKeySpecy = new SecretKeySpec(key, aesEncryptionAlgorithm);
IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpecy, ivParameterSpec);
cipherText = cipher.doFinal(cipherText);
return cipherText;
}
public byte[] encrypt(byte[] plainText, byte[] key, byte [] initialVector) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
{
Cipher cipher = Cipher.getInstance(cipherTransformation);
SecretKeySpec secretKeySpec = new SecretKeySpec(key, aesEncryptionAlgorithm);
IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
plainText = cipher.doFinal(plainText);
return plainText;
}
private byte[] getKeyBytes(String key) throws UnsupportedEncodingException {
byte[] keyBytes= new byte[16];
byte[] parameterKeyBytes= key.getBytes(characterEncoding);
System.arraycopy(parameterKeyBytes, 0, keyBytes, 0, Math.min(parameterKeyBytes.length, keyBytes.length));
return keyBytes;
}
public String encrypt(String plainText, String key) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException{
byte[] plainTextbytes = plainText.getBytes(characterEncoding);
byte[] keyBytes = getKeyBytes(key);
return Base64.encodeToString(encrypt(plainTextbytes,keyBytes, keyBytes), Base64.NO_WRAP);
}
public String decrypt(String encryptedText, String key) throws KeyException, GeneralSecurityException, GeneralSecurityException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException {
byte[] cipheredBytes = Base64.decode(encryptedText, Base64.NO_WRAP);
byte[] keyBytes = getKeyBytes(key);
return new String(decrypt(cipheredBytes, keyBytes, keyBytes), characterEncoding);
}
}

AES Cipher - javax.crypto.IllegalBlockSizeException Input length must be multiple of 16 when decrypting with padded cipher

I created a class which encrypts and decrypts Strings using the AES Cipher.
But when i run my encrypt method i get an javax.crypto.IllegalBlockSizeException error
Complete Stack:
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:913)
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 CipherEncrypter.decrypt(CipherEncrypter.java:46)
at CipherEncrypter.decrypt(CipherEncrypter.java:42)
CipherEncrypter class:
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.UUID;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class CipherEncrypter extends Encrypter<SecretKeySpec> {
byte[] iv;
private Cipher cipher;
private IvParameterSpec ivSpec;
public CipherEncrypter() throws NoSuchAlgorithmException, NoSuchPaddingException {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
generateKey();
}
public String encrypt(String input) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
return new String(encrypt(input.getBytes(StandardCharsets.UTF_8)));
}
public byte[] encrypt(byte[] input) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
byte[] iv = new byte[cipher.getBlockSize()];
new SecureRandom().nextBytes(iv);
ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
byte[] encrypted = cipher.doFinal(input);
return encrypted;
}
public String decrypt(String encrypted) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
return new String(decrypt(encrypted.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
}
public byte[] decrypt(byte[] encrypted) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
byte[] decrypted = cipher.doFinal(encrypted);
System.out.println("decrypted: " + new String(decrypted, StandardCharsets.UTF_8));
return decrypted;
}
public SecretKeySpec generateKey() throws NoSuchAlgorithmException {
return generateKey(UUID.randomUUID().toString());
}
public SecretKeySpec generateKey(String seed) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(seed.getBytes());
byte[] keyBytes = new byte[16];
System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);
key = new SecretKeySpec(keyBytes, "AES");
return key;
}
}
Encrypter class:
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
public abstract class Encrypter<T> {
public T key;
public abstract String encrypt(String str) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException;
public abstract String decrypt(String str) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException;
public abstract T generateKey() throws Exception;
public void setKey(T key) { this.key = key; }
public T getKey() { return key; }
}
Edit:
29: return Base64.getEncoder().encodeToString(encrypt(input.getBytes(StandardCharsets.UTF_8)));
34: return new String(decrypt(Base64.getDecoder().decode(encrypted)), StandardCharsets.UTF_8);
now getting another Error:
java.lang.IllegalArgumentException: Illegal base64 character d
IllegalArgumentException
at java.util.Base64$Decoder.decode0(Unknown Source)
at java.util.Base64$Decoder.decode(Unknown Source)
at java.util.Base64$Decoder.decode(Unknown Source)
at CipherEncrypter.decrypt(CipherEncrypter.java:43)

How to Encrypt String With Public Key and Decrypt with Private key ?

i want to encrypt a password with a key from server and decrypt the encrypted password in serverside. this is the code i have used in my application
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package publicprivatekey;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.*;
/**
*
* #author Rajorshi
*/
public class PublicPrivateKey {
public static String getEncrypted(String data, String Key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(Key.getBytes())));
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedbytes = cipher.doFinal(data.getBytes());
return new String(Base64.getEncoder().encode(encryptedbytes));
}
public static String getDecrypted(String data, String Key) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
PrivateKey pk = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(Key.getBytes())));
cipher.init(Cipher.DECRYPT_MODE, pk);
byte[] encryptedbytes = cipher.doFinal(Base64.getDecoder().decode(data.getBytes()));
return new String(encryptedbytes);
}
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
// TODO code application logic here
KeyGenerator keyGenerator = KeyGenerator.getInstance("Blowfish");
keyGenerator.init(448);
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.genKeyPair();
String pubKey = new String(Base64.getEncoder().encode(keyPair.getPublic().getEncoded()));
String priKey = new String(Base64.getEncoder().encode(keyPair.getPrivate().getEncoded()));
System.out.println("Public Key:" + pubKey);
System.out.println("Private Key:" + priKey);
String cipherText = getEncrypted("hi this is a string", pubKey);
System.out.println("CHIPHER:" + cipherText);
String decryptedText = getDecrypted(cipherText, priKey);
System.out.println("DECRYPTED STRING:" + decryptedText);
}
}
i want to encrypt a password with a key from server and decrypt the encrypted password in serverside. this is the code i have used in my application.
If you are looking for a java program to encrypt data with public key and decrypt it with private key then here is the code (using RSA algorithm),
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
/**
* #author visruthcv
*
*/
public class CryptographyUtil {
private static final String ALGORITHM = "RSA";
public static byte[] encrypt(byte[] publicKey, byte[] inputData)
throws Exception {
PublicKey key = KeyFactory.getInstance(ALGORITHM)
.generatePublic(new X509EncodedKeySpec(publicKey));
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedBytes = cipher.doFinal(inputData);
return encryptedBytes;
}
public static byte[] decrypt(byte[] privateKey, byte[] inputData)
throws Exception {
PrivateKey key = KeyFactory.getInstance(ALGORITHM)
.generatePrivate(new PKCS8EncodedKeySpec(privateKey));
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decryptedBytes = cipher.doFinal(inputData);
return decryptedBytes;
}
public static KeyPair generateKeyPair()
throws NoSuchAlgorithmException, NoSuchProviderException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
// 512 is keysize
keyGen.initialize(512, random);
KeyPair generateKeyPair = keyGen.generateKeyPair();
return generateKeyPair;
}
public static void main(String[] args) throws Exception {
KeyPair generateKeyPair = generateKeyPair();
byte[] publicKey = generateKeyPair.getPublic().getEncoded();
byte[] privateKey = generateKeyPair.getPrivate().getEncoded();
byte[] encryptedData = encrypt(publicKey,
"hi this is Visruth here".getBytes());
byte[] decryptedData = decrypt(privateKey, encryptedData);
System.out.println(new String(decryptedData));
}
}
you can do with Scala or Spark + scala as:
object App {
def main(args: Array[String]): Unit = {
println("************hello*******************\n")
val generator = KeyPairGenerator.getInstance("RSA")
generator.initialize(2048)
val pair = generator.generateKeyPair
val privateKey = pair.getPrivate
val publicKey = pair.getPublic
//println("private key: ",privateKey)
println("public Key: ", publicKey)
//Convert the keys to string using encodeToString()
val publicKeyString = getEncoder.encodeToString(publicKey.getEncoded());
println("publicKeyString :", publicKeyString)
val privateKeyString = getEncoder.encodeToString(privateKey.getEncoded());
println("privateKeyString :", privateKeyString)
val spark = SparkSession.builder()
.master("local")
.appName("rsa_test")
.enableHiveSupport()
.config("spark.sql.parquet.compression.codec", "snappy")
.config("parquet.block.size", 268435456)
.config("hive.exec.dynamic.partition.mode", "nonstrict")
.getOrCreate()
def RsaEncryption(inParm: String): Array[Byte] = {
//Create a Cipher object.The Cipher will provide the functionality of a
// cryptographic cipher for encryption and decryption.
val encryptionCipher = Cipher.getInstance("RSA")
//init() method initializes the cipher with a key for encryption, decryption, key wrapping,
// or key unwrapping depending on the value of opmode
encryptionCipher.init(Cipher.ENCRYPT_MODE, privateKey)
//The doFinal() method performs the encryption operation depending on how the cipher was initialized
// and resets once it finishes allowing encrypting more data.
val encryptedMessage = encryptionCipher.doFinal(inParm.getBytes)
return encryptedMessage
//return encryption
}
def RsaDecryption(inParm: Array[Byte]): String = {
val decryptionCipher = Cipher.getInstance("RSA")
decryptionCipher.init(Cipher.DECRYPT_MODE, publicKey)
val decryptedMessage = decryptionCipher.doFinal(inParm)
val decryption = new String(decryptedMessage)
return decryption
}
val secretMessage = "Test string for encryption"
val encryptedMessage = RsaEncryption(secretMessage)
println("encryptedMessage is :"+encryptedMessage)
//The method returns an array of bites which is simply our message, and we can convert it to a string
// and log it to the console to verify our text is similar to the decrypted text.
System.out.println("Encrypted Message = " + getEncoder.encodeToString(RsaEncryption(secretMessage)))
// register udf below
val clearTxt = "It will be done through spark 2.12"
spark.udf.register("rsa_encrypt", (clearTxt: String) => getEncoder.encodeToString(RsaEncryption(clearTxt)))
val text = s"""select rsa_encrypt(\"$clearTxt\") as enc_string"""
println(text)
val df1 = spark.sql(text)
val encString = df1.select(col("enc_string")).collectAsList().get(0)(0).toString().getBytes()
//val encString1 = df1.withColumn("enc2",col("enc_string").cast(Array[Byte]()))
println("Showing string : " + encString)
println("Decoder call "+ getDecoder.decode(encString))
val decodedString = getDecoder.decode(encString)
def manOf[T: Manifest](t: T): Manifest[T] = manifest[T]
println("Data type of df value " + manOf(getEncoder.encodeToString(RsaEncryption(secretMessage))))
df1.show(truncate=false)
//Decrypt message
val decryptionCipher = Cipher.getInstance("RSA")
decryptionCipher.init(Cipher.DECRYPT_MODE, publicKey)
val decryptedMessage = decryptionCipher.doFinal(encryptedMessage)
val decryption = new String(decryptedMessage)
println("=>"+decryption)
//System.out.println("decrypted message = " + RsaDecryption(encryptedMessage))
System.out.println("decrypted message2 = " +RsaDecryption(decodedString))
}
}

Encrypt Decrypt my own key not generated java

I am new to cryptography, so I have a question:
How can I create my own key (let`s say like a string "1234"). Because I need to encrypt a string with a key (defined by me), save the encrypted string in a database and when I want to use it, take it from the database and decrypt it with the key known by me.
I have this code :
import java.security.InvalidKeyException;
import java.security.*;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
public class LocalEncrypter {
private static String algorithm = "PBEWithMD5AndDES";
//private static Key key = null;
private static Cipher cipher = null;
private static SecretKey key;
private static void setUp() throws Exception {
///key = KeyGenerator.getInstance(algorithm).generateKey();
SecretKeyFactory factory = SecretKeyFactory.getInstance(algorithm);
String pass1 = "thisIsTheSecretKeyProvidedByMe";
byte[] pass = pass1.getBytes();
SecretKey key = factory.generateSecret(new DESedeKeySpec(pass));
cipher = Cipher.getInstance(algorithm);
}
public static void main(String[] args)
throws Exception {
setUp();
byte[] encryptionBytes = null;
String input = "1234";
System.out.println("Entered: " + input);
encryptionBytes = encrypt(input);
System.out.println(
"Recovered: " + decrypt(encryptionBytes));
}
private static byte[] encrypt(String input)
throws InvalidKeyException,
BadPaddingException,
IllegalBlockSizeException {
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] inputBytes = input.getBytes();
return cipher.doFinal(inputBytes);
}
private static String decrypt(byte[] encryptionBytes)
throws InvalidKeyException,
BadPaddingException,
IllegalBlockSizeException {
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] recoveredBytes =
cipher.doFinal(encryptionBytes);
String recovered =
new String(recoveredBytes);
return recovered;
}
}
Exception in thread "main" java.security.spec.InvalidKeySpecException: Invalid key spec
at com.sun.crypto.provider.PBEKeyFactory.engineGenerateSecret(PBEKeyFactory.java:114)
at javax.crypto.SecretKeyFactory.generateSecret(SecretKeyFactory.java:335)
at LocalEncrypter.setUp(LocalEncrypter.java:22)
at LocalEncrypter.main(LocalEncrypter.java:28)
A KeyGenerator generates random keys. Since you know the secret key, what you need is a SecretKeyFactory. Get an instance for your algorithm (DESede), and then call its generateSecret méthode with an instance of DESedeKeySpec as argument:
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
SecretKey key = factory.generateSecret(new DESedeKeySpec(someByteArrayContainingAtLeast24Bytes));
Here is a complete example that works. As I said, DESedeKeySpec must be used with the DESede algorithm. Using a DESede key with PBEWithMD5AndDES makes no sense.
public class EncryptionTest {
public static void main(String[] args) throws Exception {
byte[] keyBytes = "1234567890azertyuiopqsdf".getBytes("ASCII");
DESedeKeySpec keySpec = new DESedeKeySpec(keyBytes);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
SecretKey key = factory.generateSecret(keySpec);
byte[] text = "Hello world".getBytes("ASCII");
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encrypted = cipher.doFinal(text);
cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decrypted = cipher.doFinal(encrypted);
System.out.println(new String(decrypted, "ASCII"));
}
}
Well, I found the solution after combining from here and there. The encrypted result will be formatted as Base64 String for safe saving as xml file.
package cmdCrypto;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.xml.bind.DatatypeConverter;
public class CmdCrypto {
public static void main(String[] args) {
try{
final String strPassPhrase = "123456789012345678901234"; //min 24 chars
String param = "No body can see me";
System.out.println("Text : " + param);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
SecretKey key = factory.generateSecret(new DESedeKeySpec(strPassPhrase.getBytes()));
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE, key);
String str = DatatypeConverter.printBase64Binary(cipher.doFinal(param.getBytes()));
System.out.println("Text Encryted : " + str);
cipher.init(Cipher.DECRYPT_MODE, key);
String str2 = new String(cipher.doFinal(DatatypeConverter.parseBase64Binary(str)));
System.out.println("Text Decryted : " + str2);
} catch(Exception e) {
e.printStackTrace();
}
}
}

Categories