how to encrypt and decrypt data between php and android - java

These are my classes used in order to encrypt and decrypt data between a php based server and an android application.
Sometimes the php decrypt class does not work:
For example when I encrypt "abc" or "zdf" or "091360532561524369510" in android, the php class could not decrypt the encrypted data from the android client side.
Can you please check these classes?
java class:
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class ApiCrypter
{
private String iv= "0123456789012345";
private String secretkey= "9876543210987654";
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
public ApiCrypter()
{
ivspec = new IvParameterSpec(iv.getBytes());
keyspec = new SecretKeySpec(secretkey.getBytes(), "AES");
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
public byte[] encrypt(String text) throws Exception
{
if(text == null || text.length() == 0) {
throw new Exception("Empty string");
}
byte[] encrypted = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(text.getBytes("UTF-8"));
}
catch (Exception e) {
throw new Exception("[encrypt] " + e.getMessage());
}
return encrypted;
}
public byte[] decrypt(String code) throws Exception
{
if(code == null || code.length() == 0) {
throw new Exception("Empty string");
}
byte[] decrypted = null;
try {
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
}
catch (Exception e) {
throw new Exception("[decrypt] " + e.getMessage());
}
return decrypted;
}
public static String bytesToHex(byte[] data)
{
if (data==null) {
return null;
}
int len = data.length;
String str = "";
for (int i=0; i<len; i++) {
if ((data[i]&0xFF)<16) {
str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
}
else {
str = str + java.lang.Integer.toHexString(data[i]&0xFF);
}
}
return str;
}
public static byte[] hexToBytes(String str) {
if (str==null) {
return null;
}
else if (str.length() < 2) {
return null;
}
else {
int len = str.length() / 2;
byte[] buffer = new byte[len];
for (int i=0; i<len; i++) {
buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
}
return buffer;
}
}
}
PHP class :
<?php
class ApiCrypter
{
private $iv = '0123456789012345';
private $key = '9876543210987654';
public function __construct()
{
}
public function encrypt($str)
{
$str = $this->pkcs5_pad($str);
$iv = $this->iv;
$td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv);
mcrypt_generic_init($td, $this->key, $iv);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return bin2hex($encrypted);
}
public function decrypt($code)
{
$code = $this->hex2bin($code);
$iv = $this->iv;
$td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv);
mcrypt_generic_init($td, $this->key, $iv);
$decrypted = mdecrypt_generic($td, $code);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$ut = utf8_encode(trim($decrypted));
return $this->pkcs5_unpad($ut);
}
protected function hex2bin($hexdata)
{
$bindata = '';
for ($i = 0; $i < strlen($hexdata); $i += 2) {
$bindata .= chr(hexdec(substr($hexdata, $i, 2)));
}
return $bindata;
}
protected function pkcs5_pad ($text)
{
$blocksize = 16;
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
protected function pkcs5_unpad($text)
{
$pad = ord($text{strlen($text)-1});
if ($pad > strlen($text))
{
return false;
}
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad)
{
return false;
}
return substr($text, 0, -1 * $pad);
}
}
?>

A couple of things:
Your IVs should be distinct per message and unpredictable; never hard-coded.
Don't use mcrypt in PHP.
This is the easiest way to solve your problem:
Get libsodium in both languages. If you upgrade your PHP to 7.2 or newer, you should get the Sodium extension automatically (unless your OS vendor is doing something wrong).
Use crypto_secretbox() (or the equivalent API in your language) to encrypt, crypto_secretbox_open() to decrypt.
This is simpler than learning the proper way to fuss about with CBC mode, Initialization Vectors, padding schemes, RNGs, and ciphertext integrity.

Related

AES Decryption - original characters replaced by weird characters

I am trying to encrypt a json string using the below code:
public static final Charset CHARSET = StandardCharsets.UTF_8;
public static Cipher getDefaultCipherInstance(int mode)
throws NoSuchPaddingException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException, InvalidKeyException {
byte[] key = Base64.getDecoder().decode("encryptionKey".getBytes(CHARSET));
IvParameterSpec iv = new IvParameterSpec("RandomVector".getBytes(CHARSET));
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(mode, skeySpec, iv);
return cipher;
}
public static String encryptText(String plainText) {
try {
Cipher cipher = getDefaultCipherInstance(Cipher.ENCRYPT_MODE);
byte[] cipherText = cipher.doFinal(plainText.getBytes(CHARSET));
return new String(Base64.getEncoder().encode(cipherText));
} catch (Exception ex) {
LOG.error("Problem encryptingText",ex);
return null;
}
}
public static String decryptText(String cipherText) {
try {
Cipher cipher = getDefaultCipherInstance(Cipher.DECRYPT_MODE);
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(cipherText));
return new String(decrypted);
} catch (Exception ex) {
LOG.debug("Problem during decrypt text: " + cipherText, ex);
return null;
}
}
It works fine most of the times but sometimes I see weird characters in the decrypted string like "\u001A=`�["Q�\u001D)��ۉ�d":\ , this is corrupting the json and we are not able to deserialize json to object.
Any idea what could be the problem here?
Update::
I added the following code to test encryption/decryption in a concurrent(multi-threaded) environment:
public class EncryptionTest {
#Test
public void test() throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(25);
String text = "Hi there Ithanks for cimngng";
for(int i = 0; i < 5; i++) {
System.out.println("Iteration: " + i);
executorService.submit(new EncryptionRunnable(text));
}
Thread.currentThread().join();
}
static class EncryptionRunnable implements Runnable {
private String text;
public EncryptionRunnable(String text) {
this.text = text;
}
#Override
public void run() {
int i = 0;
while(i < 10) {
String encrypted = encryptText(text);
String prefix = Thread.currentThread().getName() + "::" + i + ":: ";
System.out.println(prefix + "encrypted:: " + encrypted);
try {
System.out.println(prefix + "decrypted:: " + decryptText(encrypted));
} catch (Exception e) {
System.out.println(prefix + "decrypted:: ");
e.printStackTrace();
}
i++;
}
}
}
}
I see that all of the outputs were correct but for one of the output, it produced strange characters like this:
pool-1-thread-5::0:: decrypted:: ȼ����S}�q��j� for cimngng
Even the encrypted string is same for every encryption. Can anybody help now? Note: I am using the same cipher instance for encryption and same for decryption.
Here is a snapshot of the output of the above code.

Brute force attack AES 192b

I have a task where I have to brute force a .enc file encrypted with AES-192 in CBC mode.
So the first thing I've done is trying an offline dictionary attack using Java and the Crypto library, the problem is that an average word in the dictionary is 8 bit long so the password must have been salted in some way.
The problem is that the program that I wrote keep outputting different password at every execution and the output is just unreadable text.
here is the main:
public class main {
public static void main(String[] args) {
bruteForceFile();
}
/*
* Tries to brute force the file reading all the possible keys from a dictionary
* */
private static void bruteForceFile() {
System.out.println("--------------------------------------------------------");
System.out.println("Starting brute force/dictionary attack:");
try {
byte[] file = cipherText.cipherText.getInstance().getFileArray();
bruteForceWrapper enc = new AES(OperatingMode.CBC).bruteForceFile(file);
System.out.println("decription succeded, key : " + enc.key + " elapsed time: " + enc.elapsedSeconds +"s");
System.out.println("--------------------------------------------------------");
System.out.println("Decripted message:\n");
System.out.println(new String(enc.data));
}catch(Exception e) {
e.printStackTrace();
}
}
}
and here is the AES class:
/**
*Advanced Encryption Standard as specified by NIST in FIPS 197. Also known as the Rijndael
*algorithm by Joan Daemen and Vincent Rijmen,
*AES is a 128-bit block cipher supporting keys of 128, 192, and 256 bits.
*/
public class AES extends cipher.AbstractCipher {
public AES(OperatingMode opm) {
super(opm);
super.enablePadding();
}
#Override
protected String getMode() {
if(opm == OperatingMode.CBC) {
if(padding)
return "AES/CBC/PKCS5Padding";
return "AES/CBC/NoPadding";
}
else {
if(padding)
return "AES/ECB/PKCS5Padding";
return "AES/ECB/NoPadding";
}
}
#Override
public encriptionWrapper encript(byte[] plainText,AbstractCipherKey key) {
return null;
}
#Override
public encriptionWrapper decript(byte[]cipherText,AbstractCipherKey key) {
StopWatch timer = new StopWatch();
if(super.print) {
System.out.println("------------------------------------------------------------");
System.out.println("Starting " + this.toString() + " decryption" + " in "
+ opm.toString() + " mode."+ " (" + this.getMode() + ")");
}
try {
Cipher dcipher = Cipher.getInstance("AES");
AESCipherKey aes_key = (AESCipherKey)key;
byte[] b_key = aes_key.getPassword().getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
b_key = sha.digest(b_key);
b_key = Arrays.copyOf(b_key, 16);
SecretKeySpec secretKeySpec = new SecretKeySpec(b_key, "AES");
dcipher.init(Cipher.DECRYPT_MODE, secretKeySpec);// decode with base64 to get bytes
byte[] utf8 = dcipher.doFinal(cipherText);
// create new string based on the specified charset
if(super.print) {
System.out.println("Encryption ended. Elapsed Time: " + timer.getSeconds() + "s");
System.out.println("encrypted message length: " + utf8.length);
System.out.println("------------------------------------------------------------");
}
return new encriptionWrapper(utf8,timer.getSeconds());
} catch (Exception e) {
/*if(e.getClass() == BadPaddingException.class) {
System.out.println("attempt failed....");
}*/
if(super.print) {
System.out.println(this.toString() + " decryption failed. \n");
System.out.println("decryption ended. Elapsed Time: " + timer.getSeconds() + "s");
System.out.println("------------------------------------------------------------\n");
}
return null;
}
}
/*
* Try to brute force an encrypted file with AES
*/
public bruteForceWrapper bruteForceFile(byte[] encrypted) {
StopWatch watch = new StopWatch();
Dictionary dic = new Dictionary();
bruteForceWrapper wrapper;
super.print = false;
System.out.print("Decrypting...");
while(1 == 1) {
if(dic.getProvidedWords().size()%10 == 0) {
System.out.print(".");
}
encriptionWrapper enc = decript(encrypted,new AESCipherKey(dic.getWord()));
if(enc != null) {
wrapper = new bruteForceWrapper(enc.data, watch.getSeconds());
break;
}
}
super.print = true;
wrapper.tried_keys = dic.getProvidedWords();
wrapper.key = dic.getProvidedWords().get(dic.getProvidedWords().size() - 1);
return wrapper;
}
#Override
public String toString() {
return "AES";
}
}
Finally here is the AESCipherKey class:
public class AESCipherKey extends AbstractCipherKey{
private String SHA_TEC = "SHA-1";
public AESCipherKey(String key) {
super(key);
}
/**
*Return the desription of the safeness of the key(unsafe is user generated)
*/
#Override
public String getKeySafenessDescription() {
if(isKeySafe) {
return "(safe key)";
}else
return "(unsafe key)";
}
#Override
public boolean validate() {
if(super.isKeySafe)
return true;
if(super.getByteArray().length != 16) {
System.out.println("Invalid AES key: " + super.key);
return false;
}
return true;
}
#Override
public void generateSecureKey() {
KeyGenerator keyGen;
try {
keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
super.safeKey = keyGen.generateKey();
super.isKeySafe = true;
} catch (NoSuchAlgorithmException e) {
System.out.println("Error generating AES safe key");
e.printStackTrace();
}
}
public String getPassword() {
return super.key;
}
}
So I think that the problem is around here:
byte[] b_key = aes_key.getPassword().getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
b_key = sha.digest(b_key);
b_key = Arrays.copyOf(b_key, 16);
SecretKeySpec secretKeySpec = new SecretKeySpec(b_key, "AES");
but I'm not able to find the error, here some output of the decryption:
--------------------------------------------------------
Starting brute force/dictionary attack:
Decrypting................decription succeded, key : enantiopathia elapsed time: 12.995s
--------------------------------------------------------
Decripted message:
"��t����O����m�V��}s1��i#a7� B<2�B֯�R�E�\!��v���k��WK�m��'hՒ���g�y�$�s�ug���
X��l=qYX�����F%�y)���>��r܅͞��i��L'FG��c6-�}���-�|�L�#�n���Ӧ���)�\�o�2|?7/ə���Lc�����-
�/���*���"sK���*[U�ɮ�����s��ec�P��z�6v�����Ov��1e����w�5����t�{s�%���|��W���'�3�^�H�Td��k1���S���l�8��Žѕ���XZ�X�Eiq��K���|�'�Wi��
E2-�k�Zm��
�͞�+tj��p�o\m���jc\���ؠ_v�F�k;���$\O��JW!�zD3cZ�#���N�T�J!^c��<��+���)[sK�=�Sf���Tm���J>�i�tc���1��`ɱs
,,uO��zt� �Ү>j�6��xe�,�z��l�$jW�����n��g��~M��^�s-����}kDr���`ݶ��4��?��hT�G�߿E�Z�w����&��'��фAz��}�-��r�W�2=����ƛ�i�!��Ⱥu�J�8_d��z���9h�]��yi�A�6D�0H�R����g#��������>rS1�e�供�F����H�E[m�����Syc��糠�)��"��b�޻�0%�¤����
o70T&&�T�06�q�F��X`�V��u{1`&Xkx ��7�����|�v
2_�y��VL6z�xu��95�r�H'g�E�J�(\WY�T������T���kXM�bG�^kppڀ#�h�1�9�[���Ǽ�T<�/Oo�B =�iw����Ef��G�S�c<����������W�
�<�H�N����$�m�-=�;�*��].��v��n���&�V��D����_�{9��+��:����̶F0��|�1�9��p�9�* �Rs�Ͱ�Ckl5ͫ�jGB��!��m�h
/��*г-�z�H�w�)Q����p��!� B�p�H֌˦eOŹ��������< ��Ǹ��[����uP��q�n�T���Lj����yrЙ-$�i��X����T~�R��4�xό~]��G��e�dÖnI��&b{�=�&��Bi�y���%|���E���H�=�k�~į_�6PӬ׫��D|~
M ;��BK�'�p����o:8��0]������ً �&�k9��2�0�̟WtFy���t�>?GS��� W.����tG�R��$\V�'�����'�&��a����#�b�9�בȨ�yl�+J�M���rƠ�D�0H��B�w;��8\�!���.%��yc��~�9�X ;hq�)�&E�
�W��?�D�-:��,t�f柟.�-P�f�\˲�=S.�&
���X޳]�����Z��׸���������j�A(�]�����m�*U'"6��g��jw��

Converting java to php - AES encryption with keystore.jks file

I am trying to convert a Java encryption and decryption method to PHP.
It is a AES encryption/decryption method with keystore.jks file. I am finding it difficult to achieve this.
I have tried converting using mcrypt_encrypt method in PHP. But couldn't find a way to do it with keystore.jks file.
It will be great if you guys can comment what does each important line do.
function my_aes_encrypt($key, $data) {
if(16 !== strlen($key)) $key = hash('MD5', $key, true);
$padding = 16 - (strlen($data) % 16);
$data .= str_repeat(chr($padding), $padding);
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB, str_repeat("\0", 16)));
}
function my_aes_decrypt($str, $key){
$str = base64_decode($str);
$str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB);
$block = mcrypt_get_block_size('rijndael_128', 'ecb');
$pad = ord($str[($len = strlen($str)) - 1]);
$len = strlen($str);
$pad = ord($str[$len-1]);
return substr($str, 0, strlen($str) - $pad);
}
public class MainClass {
public static void main(String[] args) {
try {
String ALIAS = "alias";
String KEYSTORE_PASSWORD = "key_pass";
String KEY_PASSWORD = "k_pass";
KeyStore keyStore = KeyStore.getInstance("JCEKS");
FileInputStream stream = new FileInputStream("path/to/keyFile.jks");
keyStore.load(stream, KEYSTORE_PASSWORD.toCharArray());
Key key = keyStore.getKey(ALIAS, KEY_PASSWORD.toCharArray());
String data = "text to encrypt";
//Encrypt Data
String encryptedData = encryptWithAESKey(data, key.getEncoded());
System.out.println("Encrypted Data : " + encryptedData);
//Decrypt Data
System.out.println("Decrypted Data : " +decryptWithAESKey(encryptedData, key.getEncoded()));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String encryptWithAESKey(String data, byte[] key) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
SecretKey secKey = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secKey);
byte[] newData = cipher.doFinal(data.getBytes());
return Base64.encodeBase64String(newData);
}
public static String decryptWithAESKey(String inputData, byte[] key) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = Cipher.getInstance("AES");
SecretKey secKey = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, secKey);
byte[] newData = cipher.doFinal(Base64.decodeBase64(inputData.getBytes()));
return new String(newData);
}
}
php code does nothing - this is only encryption and decryption procedures;
java code encrypts data with encryptWithAESKey() and then decrypt it with decryptWithAESKey(). Key is loaded from file "path/to/keyFile.jks" (fake path, you can change it) Do you have this keys file?
Look at my encoder class:
<?php
class AES {
const M_CBC = 'cbc';
const M_CFB = 'cfb';
const M_ECB = 'ecb';
const M_NOFB = 'nofb';
const M_OFB = 'ofb';
const M_STREAM = 'stream';
protected $key;
protected $cipher;
protected $data;
protected $mode;
protected $IV;
/**
*
* #param type $data
* #param type $key
* #param type $blockSize
* #param type $mode
*/
function __construct($data = null, $key = null, $blockSize = null, $mode = null) {
$this->setData($data);
$this->setKey($key);
$this->setBlockSize($blockSize);
$this->setMode($mode);
$this->setIV("");
}
/**
*
* #param type $data
*/
public function setData($data) {
$this->data = $data;
}
/**
*
* #param type $key
*/
public function setKey($key) {
$this->key = $key;
}
/**
*
* #param type $blockSize
*/
public function setBlockSize($blockSize) {
switch ($blockSize) {
case 128:
$this->cipher = MCRYPT_RIJNDAEL_128;
break;
case 192:
$this->cipher = MCRYPT_RIJNDAEL_192;
break;
case 256:
$this->cipher = MCRYPT_RIJNDAEL_256;
break;
}
}
/**
*
* #param type $mode
*/
public function setMode($mode) {
switch ($mode) {
case AES::M_CBC:
$this->mode = MCRYPT_MODE_CBC;
break;
case AES::M_CFB:
$this->mode = MCRYPT_MODE_CFB;
break;
case AES::M_ECB:
$this->mode = MCRYPT_MODE_ECB;
break;
case AES::M_NOFB:
$this->mode = MCRYPT_MODE_NOFB;
break;
case AES::M_OFB:
$this->mode = MCRYPT_MODE_OFB;
break;
case AES::M_STREAM:
$this->mode = MCRYPT_MODE_STREAM;
break;
default:
$this->mode = MCRYPT_MODE_ECB;
break;
}
}
private function pkcs5_pad ($text, $blocksize) {
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
/**
*
* #return boolean
*/
public function validateParams() {
if ($this->data != null && $this->key != null && $this->cipher != null) {
if(strlen($this->key) > 16) $this->setKey(substr($this->key, 0, 16));
if(strlen($this->key) < 16){ $n = 1 + intval(16 / strlen($this->key)); $this->setKey(substr(str_repeat($this->key, $n), 0, 16));}
$size = mcrypt_get_block_size($this->cipher, $this->mode);
$this->data = $this->pkcs5_pad($this->data, $size);
return true;
} else {
return FALSE;
}
}
public function setIV($IV) {
$this->IV = $IV;
}
protected function getIV() {
if ($this->IV == "") {
$this->IV = mcrypt_create_iv(mcrypt_get_iv_size($this->cipher, $this->mode), MCRYPT_RAND);
}
return $this->IV;
}
/**
* #return type
* #throws Exception
*/
public function encrypt() {
if ($this->validateParams()) {
return trim(base64_encode(
mcrypt_encrypt(
$this->cipher, $this->key, $this->data, $this->mode, $this->getIV())));
} else {
throw new Exception('Invlid params!');
}
}
/**
*
* #return type
* #throws Exception
*/
public function decrypt() {
if ($this->validateParams()) {
return trim(mcrypt_decrypt(
$this->cipher, $this->key, base64_decode($this->data), $this->mode, $this->getIV()));
} else {
throw new Exception('Invlid params!');
}
}
}
and usage example:
$crypt = new AES('{"username":"Tiger","amount":20,"source":1,"ttime":1517405737}', "49c50ba2129b7730", 128);
$encdata = $crypt->encrypt();
$crypt = new AES($encdata, "49c50ba2129b7730", 128);
$data = $crypt->decrypt();

Java equivalent of C# RSACryptoServiceProvider

I am a newbie to Encryption algos and C# code.
I am trying to get some data which is being encrypted decrypted using RSA algo in C# code. Below is C# code. I can't find any similar library in Java, can you help me with getting a java equivalent for the same.
public byte[] Encrypt(byte[] data, string keyContainerName, bool doOaepPadding = false)
{
return DoCryptoTransformation(data, true, keyContainerName, doOaepPadding);
}
public byte[] Decrypt(byte[] data, string keyContainerName, bool doOaepPadding = false)
{
return DoCryptoTransformation(data, false, keyContainerName, doOaepPadding);
}
private byte[] DoCryptoTransformation(byte[] data, bool encryption, string keyContainerName,
bool doOaepPadding = false)
{
try
{
byte[] processedData;
RSACryptoServiceProvider.UseMachineKeyStore = true;
CspParameters cspParams = CreateCspParameters(keyContainerName);
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cspParams))
{
processedData = encryption ? rsa.Encrypt(data, doOaepPadding) : rsa.Decrypt(data, doOaepPadding);
}
return processedData;
}
catch (CryptographicException ex)
{
string message = string.Format("RsaCryptoProvider: Failed to {0} data.", encryption ? "encrypt" : "decrypt");
Logger.Error("{0}. Exception details: {1}", message, ex);
throw new CryptoProviderException(message, ex);
}
}
private static CspParameters CreateCspParameters(string keyContainerName)
{
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = keyContainerName;
cspParams.Flags |= CspProviderFlags.UseExistingKey;
cspParams.Flags |= CspProviderFlags.UseMachineKeyStore;
return cspParams;
}
}
The methods used which I want to redefine implementation for in java:
var previousKey = _encryptionService.RsaDecrypt(Key, CoreSettings.Instance.KeyContainerName);
Thanks for help!

java.security.InvalidKeyException: unknown key type passed to RSA

i am using shared preferences to store the user name and password in order to achieve onetime user authentication. I am encrypting and storing the data in shared pref file. Again i am decrypting them and validating the values every time the user open the application. It is working fine until the App is running on background.
If the user close the app from background i am again getting the login screen asking to input the user credentials.
Below is the error:
W/System.err: java.security.InvalidKeyException: unknown key type passed to RSA
W/System.err: at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineInit(CipherSpi.java:275)
W/System.err: at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineInit(CipherSpi.java:379)
W/System.err: at javax.crypto.Cipher.init(Cipher.java:661)
W/System.err: at javax.crypto.Cipher.init(Cipher.java:621)
Below is my encryption Algorithm. I am calling the genereteKey() method before comitting the data in to shared pref file and encrypting the data then commiting the data.
private final static String RSA = "RSA";
public static PublicKey uk;
public static PrivateKey rk;
public static void generateKey() throws Exception {
KeyPairGenerator gen = KeyPairGenerator.getInstance(RSA);
gen.initialize(512, new SecureRandom());
KeyPair keyPair = gen.generateKeyPair();
uk = keyPair.getPublic();
rk = keyPair.getPrivate();
}
private static byte[] encrypt(String text, PublicKey pubRSA) throws Exception {
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.ENCRYPT_MODE, pubRSA);
return cipher.doFinal(text.getBytes());
}
public final static String encrypt(String text) {
try {
return byte2hex(encrypt(text, uk));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public final static String decrypt(String data) {
try {
return new String(decrypt(hex2byte(data.getBytes())));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static byte[] decrypt(byte[] src) throws Exception {
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.DECRYPT_MODE, rk);
return cipher.doFinal(src);
}
public static String byte2hex(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0xFF);
if (stmp.length() == 1) hs += ("0" + stmp);
else
hs += stmp;
}
return hs.toUpperCase();
}
public static byte[] hex2byte(byte[] b) {
if ((b.length % 2) != 0) throw new IllegalArgumentException("hello");
byte[] b2 = new byte[b.length / 2];
for (int n = 0; n < b.length; n += 2) {
String item = new String(b, n, 2);
b2[n / 2] = (byte) Integer.parseInt(item, 16);
}
return b2;
}

Categories

Resources