Getting the Hex String from cipherText in Net Core - java

Currently doing a encryption in java which takes
API Secret. Perform Secret key hash algorithm by using SHA256. The resulted hash algorithm would be Encrypted Key = SHA256 (API Secret)
Request Raw Parameter(param) in JSon format encrypted using the Encrypted Key trough the AES/ECB/PKCS5Padding algorithm, and the ciphertext is converted into hexadecimal characters to be the value of the Encrypted data
Encrypted Data = aesEcbPkcs5Padding (param, Encrypted key)
Here are the codes in Java
public static byte[] aesEcbPkcs5PaddingEncrypt(String content, String key) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] aesKey = digest.digest(key.getBytes());
SecretKey secretKey = new SecretKeySpec(aesKey,"AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(content.getBytes("utf-8"));
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
I Need to do the same encryption but using Net Core and C#.This is the code in C# Net Core
All i can do is something like this.
public static byte[] aesEcbPkcs5PaddingEncrypt(String content, string secretKey)
{
byte[] hashBytes = Encoding.UTF8.GetBytes(secretKey);
byte[] cipher_content = Encoding.UTF8.GetBytes(content);
using (AesManaged aes = new AesManaged())
{
byte[] encrypted = Encrypt(raw, aes.Key, aes.IV);
// Print encrypted string
Console.WriteLine($ "Encrypted data: {System.Text.Encoding.UTF8.GetString(encrypted)}");
// Decrypt the bytes to a string.
string decrypted = Decrypt(encrypted, aes.Key, aes.IV);
}
SHA256 sha256 = SHA256Managed.Create();
byte[] cryptPassword = sha256.ComputeHash(hashBytes);
}
Is there any better solution/Correct solution in net core which will resulted with the same result as Java?

Related

Android Decryption Throwing java.security.InvalidAlgorithmParameterException: IV must be specified in CBC mode

Despite checking that both my IV and derived keys are equal for encryption and decryption, it still throws the same error. The byte array will encrypt no problem, but decryption always fails. My decryption and encryption code looks like:
private final static int BLOCK_SIZE = 256;
private final static int IV_SIZE = 16;
private final static int ITERATION_COUNT = 10;
private final static String ENCRYPTION_ALGORITHM = "PBKDF2WithHmacSHA256";
private final static String ALGORITHM = "AES/CBC/PKCS5Padding";
public byte[] encryptByteArray(byte[] plaintext, String fileName) throws InvalidKeyException
{
extractIVfromName(fileName);
genKey();
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
GCMParameterSpec parameterSpec = new GCMParameterSpec(BLOCK_SIZE, iv);
Log.d("encryptByteArray", "Size: " + plaintext.length + " IV SPEC: " +
Base64.encodeToString(parameterSpec.getIV(), Base64.DEFAULT) + "DerivedKey: " +
Base64.encodeToString(derivedKey.getEncoded(), Base64.DEFAULT));
cipher.init(Cipher.ENCRYPT_MODE, derivedKey, parameterSpec);
return cipher.doFinal(plaintext);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return null;
}
And here we have decryption, where the error is occuring:
public byte[] decryptByteArray(byte[] ciphertext, String fileName) throws InvalidKeyException
{
extractIVfromName(fileName);
genKey();
try {
//IV fails for some reason
Cipher cipher = Cipher.getInstance(ALGORITHM);
GCMParameterSpec parameterSpec = new GCMParameterSpec(BLOCK_SIZE, iv);
Log.d("decryptByteArray", "Size: " + ciphertext.length + " IV SPEC: " +
Base64.encodeToString(parameterSpec.getIV(), Base64.DEFAULT) + "DerivedKey: " +
Base64.encodeToString(derivedKey.getEncoded(), Base64.DEFAULT));
cipher.init(Cipher.DECRYPT_MODE, derivedKey, parameterSpec);
return cipher.doFinal(ciphertext);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
An example of the debug log gives this:
2020-07-26 22:40:03.667 9089-9089/com.iso.gallery256 D/decryptByteArray: Size: 45312 IV SPEC: NWZmYmUzZGItZGE4MS00Yw==
DerivedKey: pa2OYoRLjTphldeSi1L6EQCmlXTzQJLeXgPIuu6kRus=
2020-07-26 22:40:00.184 9089-9089/com.iso.gallery256 D/encryptByteArray: Size: 45307 IV SPEC: NWZmYmUzZGItZGE4MS00Yw==
DerivedKey: pa2OYoRLjTphldeSi1L6EQCmlXTzQJLeXgPIuu6kRus=
I don't think the problem is with how the IV or key are generated, since they come out exactly the same for decryption and encryption, but rather with my cipher options.

Why does encrypting in one Java class and decrypting in another causes BadPaddingError?

I have a test function that returns a byte[] in one Java class, FirstClass:
public static byte[] testA(){
CipherClass crypto = new CipherClass();
byte[] a = crypto.encrypt("helloWorld");
return a;
}
Where CipherClass contains my java.crypto.Cipher methods to encrypt and decrypt inputs.
In another Java class, SecondClass, I instantiate my previous FirstClass and call its testA() method which I save to a byte[] variable and then try to decrypt it:
FirstClass fc = new FirstClass();
byte[] b = fc.testA();
System.out.println(crypto.decrypt(b)); //Outputs BadPaddingError
Why does encrypting a String in one Java file and then passing the resulting byte[] into another Java file to decrypt it causes a BadPaddingError?
What can be done to fix a way around this?
Why does the Cipher only work if both encryption and decryption are in the same class as follows?:
CipherClass crypto = new CipherClass();
byte[] a = crypto.encrypt("helloWorld"); //Outputs [B#5474c6c
byte[] b = a;
System.out.println(crypto.decrypt(b)); //Outputs "helloWorld"
EDIT: My CipherClass code as requested below.
SecretKey and IVParameterSpec generator:
public List<KeyGenerator> getKeyGenerator(){
List<KeyGenerator> list = new ArrayList<KeyGenerator>();
KeyGenerator keyGenerator;
int keyBitSize = 128;
try
{
SecureRandom secureRandom = new SecureRandom();
keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(keyBitSize, secureRandom);
list.add(keyGenerator);
return list;
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
return list;
}
public List<SecretKey> getSecretKey(List<KeyGenerator> keygen) {
List<SecretKey> list = new ArrayList<SecretKey>();
KeyGenerator keyGenerator;
SecretKey secretKey;
keyGenerator = keygen.get(0);
secretKey = keyGenerator.generateKey();
list.add(secretKey);
return list;
}
public List<IvParameterSpec> getIvSpec(List<SecretKey> secretKey) {
List<IvParameterSpec> list = new ArrayList<IvParameterSpec>();
Cipher cipher;
byte[] iv;
try
{
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
iv = new byte[cipher.getBlockSize()];
IvParameterSpec ivSpec = new IvParameterSpec(iv);
list.add(ivSpec);
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (NoSuchPaddingException e)
{
e.printStackTrace();
}
return list;
}
List<KeyGenerator> kgList = getKeyGenerator();
List<SecretKey> skList = getSecretKey(kgList); //skList.get(0) is the SecretKey
List<IvParameterSpec> ivList = getIvSpec(skList); //ivList.get(0) is the IVParameterSpec
My encrypt() method:
public byte[] encrypt(String inputStr) {
Cipher cipher;
SecretKey secretKey = skList.get(0);
IvParameterSpec ivSpec = ivList.get(0);
byte[] plainText;
byte[] cipherText = new byte[]{};
try
{
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
try
{
secretKey = skList.get(0);
ivSpec = ivList.get(0);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
try
{
plainText = inputStr.getBytes("UTF-8");
cipherText = cipher.doFinal(plainText);
return cipherText;
}
catch (IllegalBlockSizeException e)
{
e.printStackTrace();
}
catch (BadPaddingException e)
{
e.printStackTrace();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
catch (InvalidKeyException e)
{
e.printStackTrace();
}
catch (InvalidAlgorithmParameterException e1)
{
e1.printStackTrace();
}
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (NoSuchPaddingException e)
{
e.printStackTrace();
}
return cipherText;
}
My decrypt() method:
public String decrypt(byte[] cipherText){
Cipher cipherDe;
SecretKey secretKey = skList.get(0);
IvParameterSpec ivSpec = ivList.get(0);
byte[] deciByte;
String decryptText = "";
try
{
cipherDe = Cipher.getInstance("AES/CBC/PKCS5Padding");
try
{
secretKey = skList.get(0);
ivSpec = ivList.get(0);
cipherDe.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
try
{
//De-cryption
deciByte = cipherDe.doFinal(cipherText);
decryptText = new String(deciByte);
return decryptText;
}
catch (IllegalBlockSizeException e)
{
e.printStackTrace();
}
catch (BadPaddingException e)
{
e.printStackTrace();
}
}
catch (InvalidKeyException e)
{
e.printStackTrace();
}
//De-cryption
catch (InvalidAlgorithmParameterException e1)
{
e1.printStackTrace();
}
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (NoSuchPaddingException e)
{
e.printStackTrace();
}
return decryptText;
}

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.

How to implement AES encryption in Ruby

guys
Here's a snippet of code of Java about AES encrypt:
import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.utils.Base64;
...
public static String encrypt(String content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] byteContent = content.getBytes("utf-8");
byte[] result = cipher.doFinal(byteContent);
return Base64.encode(result);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
Now I try to implement it in Ruby(not work):
def self.aes128_encrypt(password, content)
cipher = OpenSSL::Cipher.new('AES-128-ECB')
cipher.encrypt
cipher.key = password
result = cipher.update(content) + cipher.final
Base64.encode64(result).chomp
end
After some research, I think the problem is the cipher#key: In Java, it's generate by securerandom with password as seed, But in Ruby, I use the password directly.
So I want to generate key like Java. But I find the random number generator used by Java is NativePRNG, which I do not find the same implementation so far.
Now, I want to ask help from guys familiar with Ruby and Java:
How can I implement the same AES encrypt in Ruby?
Or how to generate random string in Ruby with NativePRNG.
Any advice is welcome, and Thank you very much for each reply.

RSA Enabled Simple Java Chat - Not PKCS#1 block type 2 or Zero padding

I created a simple java chat application . Below is the follow
Run ChatClient.java - Dialog box is shown where user enters username. Then private key and public key are generated and stored in C:/username/publickey,C:/username/privatekey.
Above step repeats when we run ChatClient.java again.
Then user1 sends message to User2 in encrypted form using User2 public key (Which is working fine)(after encryption , message is stored in text file) then User2 clicks decrypt button which decrypts the text (reads the encrypted text from file) using User 2 private key then display in textarea.
When I trying to decrypt I am getting "Not PKCS#1 block type 2 or Zero padding" exception
public static byte[] encrypt(String text, PublicKey key) throws {
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance(ALGORITHM);
// encrypt the plain text using the public key
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = cipher.doFinal(text.getBytes("UTF8"));
return org.apache.commons.codec.binary.Base64.encodeBase64(cipherText);
}
public static String decrypt(String text, PrivateKey key) throws {
byte[] dectyptedText = null;
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance(ALGORITHM);
// decrypt the text using the private key
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] byteCipherText =org.apache.commons.codec.binary.Base64.decodeBase64(text):
byte[] cipherData = cipher.doFinal(byteCipherText);
return new String(dectyptedText);
}
private void btnDecryptActionPerformed(ActionEvent evt) throws {
String name11 = this.getTitle();
String test90 = null;
String PRIVATE_KEY_FILE = "C:/keys/"+name11+"/private.key";
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader("cipher.txt"));
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
while(in.ready())
{
String stest= in.readLine();
test90 = stest;
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
ObjectInputStream inputStream = null;
try {
inputStream = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
PrivateKey privateKey = null;
try {
privateKey = (PrivateKey) inputStream.readObject();
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
inputStream = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
PrivateKey privatekey = (PrivateKey) inputStream.readObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String plainText;
// byte[] test100 = test90.getBytes();
// out.println(test100);
plainText = decrypt(test90, privateKey); (Getting Error Here)
decryptText.append(plainText);
}
The highlighted code below means test90 only contains the last line in the cipher.txt file. Does cipher.txt contain 1 line only? If you want to read in everything, you need to concatenate each line as you read it in.
while(in.ready())
{
String stest= in.readLine();
test90 = stest;
}
It is also a good idea to System.out the variable test90 in the decrypt method to be sure that you're getting the expected base64 data to be decrypted.

Categories

Resources