lHash mismatch error in decryption with HSM stored key - encryption

In decryption of encrypted key i receive lhash mismatch error. The key is encrypt with RSA/ECB/OAEPWithSHA-1AndMGF1Padding . I used PKCS#11 provider . this is my code. Please provide solution for this ..
public class DataDecryptorNew {
private static final int PUBLIC_KEY_SIZE = 294;
private static final int EID_SIZE = 32;
private static final int SECRET_KEY_SIZE = 256;
private static final String TRANSFORMATION2 = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";
private static final String TRANSFORMATION3 = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
private static final String SECURITY_PROVIDER = "BC";
private static SunPKCS11 providerPKCS11;
private static String provider;
private static final String DIGEST_ALGORITHM = "SHA-256";
private static final String MASKING_FUNCTION = "MGF1";
private static final int VECTOR_SIZE = 16;
private static final int HMAC_SIZE = 32;
private static final int BLOCK_SIZE = 128;
private static final byte[] HEADER_DATA = "VERSION_1.0".getBytes();
private static final String SIGNATURE_TAG = "Signature";
private static final String MEC_TYPE = "DOM";
public static final String DLL = "C:\\pkcs11\\cknfast.dll";
public static String alias = "";
public static int keyLength = 2048;
private static final String password = "";
public static final String storeType = "PKCS11-nCipher";
private PrivateKey privateKey;
private PublicKey publicKey;
private KeyStore.PrivateKeyEntry keyEntry;
private KeyStore keyEntry1;
static {
Security.addProvider(new BouncyCastleProvider());
}
public byte[] decrypt(byte[] data) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, IOException, CertificateException, Exception {
if (data == null || data.length == 0) {
throw new Exception("byte array data can not be null or blank array.");
}
PrivateKey key = getPrivateKey();
ByteArraySpliter arrSpliter = new ByteArraySpliter(data);
byte[] secretKey = decryptSecretKeyData(arrSpliter.getEncryptedSecretKey(), arrSpliter.getIv(), key);
byte[] plainData = decryptData(arrSpliter.getEncryptedData(), arrSpliter.getIv(), secretKey);
boolean result = validateHash(plainData);
if (!result) {
throw new Exception("Integrity Validation Failed : "
+ "The original data at client side and the decrypted data at server side is not identical");
}
return trimHMAC(plainData);
}
private KeyStore.PrivateKeyEntry getKeyFromFile(String keyStoreFile, char[] keyStorePassword) {
try {
// Load the KeyStore and get the signing key and certificate.
KeyStore ks = KeyStore.getInstance("PKCS12");
FileInputStream keyFileStream = new FileInputStream(keyStoreFile);
ks.load(keyFileStream, keyStorePassword);
String alias = ks.aliases().nextElement();
KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias, new KeyStore.PasswordProtection(keyStorePassword));
if (entry == null) {
throw new Exception("Key not found for the given alias.");
}
keyFileStream.close();
return entry;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static PrivateKey getPrivateKey() throws Exception {
String config = "name=nCipher\n"
+ "library=" + DLL + "\n"
+ "slotListIndex = 0 ";
ByteArrayInputStream bais = new ByteArrayInputStream(config.getBytes());
Provider p = new SunPKCS11(bais);
Security.addProvider(p);
KeyStore ks = KeyStore.getInstance("PKCS11", p);
ks.load(null, "".toCharArray());
System.out.println("Keystore size : " + ks.size());
String alias = "ncipher-cert/cn=(n)code solutions ca 2014,2.5.4.51=#13133330312c20474e464320496e666f746f776572,street=bodakdev\\, s g road\\, ahmedabad,st=gujarat,2.5.4.17=#1306333830303534,ou=certifying authority,o=gujarat narmada valley fertilizers and chemicals limited,c=in/1396768448";
KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(password.toCharArray());
KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias, protParam);
// get my private key
PrivateKey key = pkEntry.getPrivateKey();
if (key instanceof PrivateKey) {
// Get certificate of public key
Certificate cert = ks.getCertificate(alias);
System.out.println(">>>>>>>>>" + ((X509Certificate) cert).getSerialNumber().toString(16));
// Get public key
PublicKey publicKey = cert.getPublicKey();
//Get Private Key
Key privatekey = (PrivateKey) key;
System.out.println("privatekey=" + privatekey);
}
return (PrivateKey) key;
}
private byte[] decryptSecretKeyData(byte[] encryptedSecretKey, byte[] iv) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, IOException, CertificateException, Exception {
try {
PrivateKey key = (PrivateKey) getPrivateKey();
System.out.println("Private Key:" + getPrivateKey().getFormat());
Cipher decCipher = Cipher.getInstance("RSA/ECB/NoPadding");
decCipher.init(Cipher.DECRYPT_MODE, key);
byte[] decipheredText = null;
decipheredText = decCipher.doFinal(encryptedSecretKey);
System.out.println("OAEP padded plain text: " + Arrays.toString(decipheredText));
if (decipheredText.length < keyLength / 8) {
byte[] tmp = new byte[(keyLength / 8) - 42];
System.arraycopy(decipheredText, 0, tmp, tmp.length - decipheredText.length, decipheredText.length);
System.out.println("Zero padding to " + (keyLength / 8));
decipheredText = tmp;
}
PSource pSrc = (new PSource.PSpecified(new byte[256]));
OAEPParameterSpec paramSpec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA1, pSrc);
RSAPadding padding = RSAPadding.getInstance(RSAPadding.PAD_OAEP_MGF1, keyLength / 8, new SecureRandom(), paramSpec);
System.out.println("PaddedPlainText length: " + decipheredText.length); //256
byte[] plainText2 = padding.unpad(decipheredText, 0, decipheredText.length);
System.out.println("Unpadded plain text: " + DatatypeConverter.printHexBinary(plainText2));
System.out.println("Decrypted Value:" + new String(plainText2));
return plainText2;
} catch (GeneralSecurityException e) {
e.printStackTrace();
throw new Exception("Failed to decrypt AES secret key using RSA.", e);
}
}
private static class ByteArraySpliter {
private final byte[] headerVersion;
private final byte[] iv;
private final byte[] encryptedSecretKey;
private final byte[] encryptedData;
private final byte[] publicKeyData;
public ByteArraySpliter(byte[] data) throws Exception {
int offset = 0;
headerVersion = new byte[HEADER_DATA.length];
copyByteArray(data, 0, headerVersion.length, headerVersion);
offset = offset + HEADER_DATA.length;
publicKeyData = new byte[PUBLIC_KEY_SIZE];
copyByteArray(data, offset, publicKeyData.length, publicKeyData);
offset = offset + PUBLIC_KEY_SIZE;
iv = new byte[EID_SIZE];
copyByteArray(data, offset, iv.length, iv);
offset = offset + EID_SIZE;
encryptedSecretKey = new byte[SECRET_KEY_SIZE];
copyByteArray(data, offset, encryptedSecretKey.length, encryptedSecretKey);
offset = offset + SECRET_KEY_SIZE;
encryptedData = new byte[data.length - offset];
copyByteArray(data, offset, encryptedData.length, encryptedData);
}
public byte[] getIv() {
return iv;
}
public byte[] getEncryptedSecretKey() {
return encryptedSecretKey;
}
public byte[] getEncryptedData() {
return encryptedData;
}
private void copyByteArray(byte[] src, int offset, int length, byte[] dest) throws Exception {
try {
System.arraycopy(src, offset, dest, 0, length);
} catch (Exception e) {
throw new Exception("Decryption failed, Corrupted packet ", e);
}
}
}
private byte[][] split(byte[] src, int n) {
byte[] l, r;
if (src == null || src.length <= n) {
l = src;
r = new byte[0];
} else {
l = new byte[n];
r = new byte[src.length - n];
System.arraycopy(src, 0, l, 0, n);
System.arraycopy(src, n, r, 0, r.length);
}
return new byte[][]{l, r};
}
public byte[] generateHash(byte[] message) throws Exception {
byte[] hash = null;
try {
MessageDigest digest = MessageDigest.getInstance(DIGEST_ALGORITHM, SECURITY_PROVIDER);
digest.reset();
hash = digest.digest(message);
} catch (GeneralSecurityException e) {
throw new Exception("SHA-256 Hashing algorithm not available");
}
return hash;
}
public static void main(String[] args) throws Exception {
String var = "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";
CustomBase64 base64 = new CustomBase64();
DataDecryptorNew decryptor = new DataDecryptorNew();
decryptor.decrypt(Base64.decode(var.getBytes()));
}
}
The error which i received is following.
Exception in thread "main" javax.crypto.BadPaddingException: lHash mismatch
at in.gov.uidai.kyc.client.RSAPadding.unpadOAEP(RSAPadding.java:396)
at in.gov.uidai.kyc.client.RSAPadding.unpad(RSAPadding.java:244)
at in.gov.uidai.kyc.client.RSAPadding.unpad(RSAPadding.java:227)
at in.gov.uidai.kyc.client.AsymmetricEncryptionExample.performEncryptDecrypt(AsymmetricEncryptionExample.java:127)
at in.gov.uidai.kyc.client.AsymmetricEncryptionExample.main(AsymmetricEncryptionExample.java:68)

There are 2 things that i have noticed in your piece of code :-
While initializing the PSource don`t initialize "iv" parameter it again , instead use the argument value from the method .
So instead of using
`PSource pSrc = (new PSource.PSpecified(new byte[256]));`
try using
PSource pSrc = (new PSource.PSpecified(iv));
Also in the you are using SHA-256 , however while initializing OAEPParameterSpec used for OAEP padding , you are using SHA-1 instead of SHA-256 for MGF1ParameterSpec
So instead of using
OAEPParameterSpec paramSpec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA1, pSrc);
try using :-
OAEPParameterSpec paramSpec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, pSrc);
Hope this will work for you...
Cheers!!

Related

The parameter is incorrect while rsa.Decrypt

getting an error "The parameter is incorrect" while using rsa.Decrypt method the public/private key is same while encrypt/decrypt. can someone help me where I'm doing wrong?
private const string Key = #"PABSAFMAQQBLAGUAeQBWAGEAbAB1AGUAPgA8AE0AbwBkAHUAbAB1AHMAPgBxAGcAMwA3AFYAUQA1AE8AdQBuADQAMwBDAEIAbQBkAEMATQB4AFMASQB6ADkAYQA2AHoAdgBMAEgAMAA5AGcAQgBvAG0AQwA1AEwARgBTAFkASABJAEcAZgAvAEUAZQBTAE4ASgBWAHUALwBBAEwAegBxAEgAYwA2AGIAcwBrAFgAbwBRAEIAZgBPAEUAMQBEAGMAVABKAEkATgBZAHAAWAByAFMALwBmAG4AcQBtAC8AUAB0AGQAcgBzAFcAeAB2AGEAWABwAHMARABTAG0AZwBhAEwASgBTAEEAZgBHAEkAYQA2ADUAdABCAHkAQgB6AE8AOAB0AFcAdABYAC8AaABQAG4ATABZAG0AdwBXAGoASgBFADQAQgB5AG0AUAArAC8AdABZAFIAdAB3AHMAbQBYAG4AdQBtAEkAbgA3ADQATQBTADMANAB6AGYAdgByAGcAcwA9ADwALwBNAG8AZAB1AGwAdQBzAD4APABFAHgAcABvAG4AZQBuAHQAPgBBAFEAQQBCADwALwBFAHgAcABvAG4AZQBuAHQAPgA8AFAAPgAyAEkAZQBBAGIATwBRAEkASQBzAG0AQwBTAGEAYgBCAG8AdwB5AHQAUwB0AFMAWQBZAHkAKwBLAG0AMQBYAFcASAB6AGUAWAA3AC8AMgBCADEAbgBUAGoAaABvAFYAZwA4AHMARgBxAEcAdgB1AHIATQBTAGcAZwB0AGUAegBqAEkAZgB3AGkAYQAyAGUAMgBiAEUAeQBSAHkASgBSAG4AegB2AFYAcgA4AFEAPQA9ADwALwBQAD4APABRAD4AeQBRADIAMABjAEEAbQBrAG8AVgBrAHQANgBXAHgARABJADgAYQB2AGcAMgByAFEARgB1AEQAZgBmAGwAagBZAEgARwBhAE4AUABEAE4AdABKAG0AOABaAEYAbgBpAEEASABWAEwAagAvAHoAagBQADEAWAB3AFQAMABTAGsAagB2AHQAQgBQAGoASwBpAHEAVQBDAFkAbQBpAEkAOAA3AEEAeABBAGwAdQB3AD0APQA8AC8AUQA+ADwARABQAD4ATwAvAEYAdgBOAFQAWAAvAHAAcABuAEEAagB1AEUAeQBWAEIAQQByAFgAVAA3AHoAbgBPAG4ASgBaAG0AMQBoADUASwB5AEEAVABIAGsAUwAyADYAcgBxAFgAaABCAEkAbwBZAHUAMwA4AHgAWgBlADgAegBIAFgAdABHAFcATABEADUAcAA4AGMATgAxADYAWABBAHIAcQBoAE8AdgBJAHYAVAB1AG0ARQBRAD0APQA8AC8ARABQAD4APABEAFEAPgBWAEUAVABmAFIAVABwADEAZQAzADkAUwBoAEEAegB4AGsAegBRADYANgBuADEAQgBuAE8AVgBDAEoAOABYADcAUgB1AFEAZwAvAEkATwBkAGsAMABkAHIAbgA0AFMAQQBSAGsAbwB3ADgAQQArAFMANQBTAHMAdABiAHoAUwBzAEcAOQBWAGEARQBsADIANwBqAFAANgBBAGwAaQBwAGEAbABLADAAVwA4AHcAPQA9ADwALwBEAFEAPgA8AEkAbgB2AGUAcgBzAGUAUQA+AEsAbwBuADUAdABZAGEAdABiAEwAbwBuAFYAUQBIAHQARQAwAE0AaABCAGoASgB6ADMAUwBKAEMAegBqAEUAOQBYAHUATAB2AEcAOABaADMAcABNADgANgBGAFoAQwBxAEQALwBpAFgAbABZAEMAUgBOAEYAWQBDAGwASABNAEEAZwArAE4AbABBAGEAQwBUAGcAQwBmAG0ARAAzAEIANQA1AGEAawBHAFgAUQA9AD0APAAvAEkAbgB2AGUAcgBzAGUAUQA+ADwARAA+AFoATABsADMAWAByAC8AawB2AGUAMgA0AFoAdQBIAFUAOAA3AHMAaQBBADYASwBwAEYAYQBBAEwAQgBmAGEAYgA2AEEATgBYAE4AbQBJAFoAYQB1AHIAZgBFAHIAVQBjAHYAUQBGAG8AcQByAEwAYQBLADQAQQBRAE8ANQBrAFAAUgA3AFIAawB0AFQAVQBuAG0AWQBvAHYAbgAzAFYANgBkADUAQQBUAHcANwAxAEgASABRAE4ANgBVAEoAWABmAHgANQBWADMAdABYADYATgBpADgAawBnAEMAUAB3AEUANABFAEkAMQBqAHoAdgBQAFgARABUAFEARQBvAGsAOABGADUANwB3AFUAbQBqAFAASQAzAFMAVwA4ADEAQgBUADIANABYAHYASAA3AHEAagBEADQATwBLAHYAZgA3AE4AKwBOAG4ATQB2AEEAQQBoAGwATQBFAD0APAAvAEQAPgA8AC8AUgBTAEEASwBlAHkAVgBhAGwAdQBlAD4A";
static void Main(string[] args)
{
string pwd = "ABC1564";
string encrypt = Encrypt(pwd);
string decrypt = Decrypt(encrypt);
Console.WriteLine("Password String :- " + pwd.ToString());
Console.WriteLine("Encrypted String :- " + encrypt.ToString());
Console.WriteLine("Decrypted String :- " + decrypt.ToString());
Console.ReadLine();
}
private static string Encrypt(string data)
{
CspParameters CSPParam = new CspParameters();
CSPParam.Flags = CspProviderFlags.UseMachineKeyStore;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(CSPParam);
rsa.FromXmlString(System.Text.UnicodeEncoding.Unicode.GetString(System.Convert.FromBase64String(Key)));
return System.Convert.ToBase64String(rsa.Encrypt((new System.Text.UnicodeEncoding()).GetBytes(data), false));
}
private static string Decrypt(string Crypt)
{
// Crypt Provider
CspParameters CSPParam = new CspParameters();
CSPParam.Flags = CspProviderFlags.UseMachineKeyStore;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(CSPParam);
// Crypt Params
string k = System.Text.UnicodeEncoding.Unicode.GetString(System.Convert.FromBase64String(Key));
rsa.FromXmlString(k);
// Decrypt
byte[] bi = (new System.Text.UnicodeEncoding()).GetBytes(System.Text.UnicodeEncoding.Unicode.GetString(System.Convert.FromBase64String(Crypt)));
byte[] bdecr = rsa.Decrypt(bi, false);
// Return results
return (new System.Text.UnicodeEncoding()).GetString(bdecr);
}

PDF Signature - Embed separatly signed hash problem

I am currently working on a web application (1) which allows sending the hash of a pdf file to another application (2). The application (2) returns a signed hash.
With a console application I managed to correctly sign the file but the problem is that we need to have the hash before the Makesignature.SignDetached (*****) function
code
static void Main(string[] args)
{
string unsignedPdf = "c:\\temp\\spec.pdf";
string signedPdf = "c:\\temp\\specSigned5.pdf";
Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[1];
byte[] bytes = Convert.FromBase64String("certificate here");
var cert = new X509Certificate2(bytes);
chain[0] = new Org.BouncyCastle.X509.X509CertificateParser().ReadCertificate(cert.GetRawCertData());
using (PdfReader reader = new PdfReader(unsignedPdf))
{
using (FileStream os = File.OpenWrite(signedPdf))
{
PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
appearance.SetVisibleSignature(new Rectangle(100, 250, 250, 400), 1, "digigo2");
appearance.Reason = "Reason";
appearance.Location = "Location";
appearance.SignDate = DateTime.Now;
appearance.Certificate = chain[0];
IExternalSignature signature = new RemoteSignature();
MakeSignature.SignDetached(appearance, signature, chain, null, null, null, 0, CryptoStandard.CADES);
}
}
}
class RemoteSignature : IExternalSignature
{
public virtual byte[] Sign(byte[] message)
{
IDigest messageDigest = DigestUtilities.GetDigest(GetHashAlgorithm());
byte[] messageHash = DigestAlgorithms.Digest(messageDigest, message);
Console.WriteLine(Convert.ToBase64String(messageHash));
Console.ReadKey();
// i send the hash to the application B and i get
// the signed hash and i save it in c:/temp/signedhash.txt
string SighHashFile = "c:/temp/signedhash.txt";
string signature = File.ReadAllText(SighHashFile);
byte[] signedBytes = Convert.FromBase64String(signature);
return signedBytes;
}
public virtual String GetHashAlgorithm()
{
return "SHA-256";
}
public virtual String GetEncryptionAlgorithm()
{
return "RSA";
}
}
I tried using the MakeSignature.SignDeferred () function but the signature is still wrong
code
static void Main(string[] args)
{
string unsignedPdf = "c:/temp/spec.pdf";
string tempPdf = "c:/temp/temp.pdf";
string signedPdf = "c:/temp/Signed.pdf";
string signatureFieldName = "test";
Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[1];
byte[] bytes = Convert.FromBase64String("certificate here");
var cert = new X509Certificate2(bytes);
chain[0] = new Org.BouncyCastle.X509.X509CertificateParser().ReadCertificate(cert.GetRawCertData());
string sByte = GetBytesToSign(unsignedPdf, tempPdf, signatureFieldName, chain[0]);
Console.WriteLine(sByte);
Console.ReadLine();
// i send the hash to the application B and i get
// the signed hash and i save it in c:/temp/signedhash.txt
string SighHashFile = "c:/temp/signedhash.txt";
string signature = File.ReadAllText(SighHashFile);
EmbedSignature(tempPdf, signedPdf, signatureFieldName, signature);
}
public static string GetBytesToSign(string unsignedPdf, string tempPdf, string signatureFieldName, Org.BouncyCastle.X509.X509Certificate chain)
{
if (File.Exists(tempPdf))
File.Delete(tempPdf);
using (PdfReader reader = new PdfReader(unsignedPdf))
{
using (FileStream os = File.OpenWrite(tempPdf))
{
PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
appearance.SetVisibleSignature(new Rectangle(36, 748, 250, 400), 1, signatureFieldName);
appearance.Reason = "Reason";
appearance.Location = "Location";
appearance.SignDate = DateTime.Now;
appearance.Certificate = chain;
IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
MakeSignature.SignExternalContainer(appearance, external, 8192);
byte[] hash = DigestAlgorithms.Digest(appearance.GetRangeStream(), "SHA256");
return Convert.ToBase64String(hash);
}
}
}
public static void EmbedSignature(string tempPdf, string signedPdf, string signatureFieldName, string signature)
{
byte[] signedBytes = Convert.FromBase64String(signature);
using (PdfReader reader = new PdfReader(tempPdf))
{
using (FileStream os = File.OpenWrite(signedPdf))
{
IExternalSignatureContainer external = new MyExternalSignatureContainer(signedBytes);
MakeSignature.SignDeferred(reader, signatureFieldName, os, external);
}
}
}
private class MyExternalSignatureContainer : IExternalSignatureContainer
{
private readonly byte[] signedBytes;
public MyExternalSignatureContainer(byte[] signedBytes)
{
this.signedBytes = signedBytes;
}
public void ModifySigningDictionary(PdfDictionary signDic)
{
}
public byte[] Sign(Stream data)
{
return signedBytes;
}
}
Invalid signature

AES 256 Encryption Decryption,

Decryption logic is missing something can you please assist.
Output is not completely decrypted.
Java Encryption Logic:
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException {
try {
String in ="This is a text message";
byte[] input = in.toString().getBytes("utf-8");
String ENCRYPTION_KEY = "RW50ZXIgS2V5IEhlcmU=";
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] thedigest = md.digest(ENCRYPTION_KEY.getBytes("UTF-8"));
// SecretKeySpec skc = new SecretKeySpec(thedigest, "AES/ECB/PKCS5Padding");
SecretKeySpec skc = new SecretKeySpec(thedigest, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skc);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
// String query = Base64.encodeToString(cipherText, Base64.DEFAULT);
String query = new String(java.util.Base64.getEncoder().encode(cipherText));
System.out.println("query " + query);
// String query = new String(encode(cipherText), StandardCharsets.ISO_8859_1);
} catch(UnsupportedEncodingException e) { // TODO Auto-generated catch block
e.printStackTrace();
}
}
Nodejs Decryption Logic:
let crypto = require('crypto');
var decipher = crypto.createDecipher('aes-256-ecb', "RW50ZXIgS2V5IEhlcmU=");
decipher.setAutoPadding(false);
console.log(decipher.update("EncyptedText", 'base64', 'utf8') + decipher.final('utf8'));

Using my own key in an AES encryption algorithm implementation

I have the following code:
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class AESHelper {
public static String encrypt(String seed, String cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
}
public static String decrypt(String seed, String encrypted) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
public static String toHex(String txt) {
return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
return new String(toByte(hex));
}
public static byte[] toByte(String hexString) {
int len = hexString.length()/2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
return result;
}
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}
and the main class:
public class MainActivity extends Activity {
String seedValue = "This Is MySecure";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String normalText = "VIJAY";
String normalTextEnc;
try{
normalTextEnc = AESHelper.encrypt(seedValue, normalText);
String normalTextDec = AESHelper.decrypt(seedValue, normalTextEnc);
TextView txe = new TextView(this);
txe.setTextSize(14);
txe.setText("Normal Text ::" + normalText + " \n Encrypted Value :: " + normalTextEnc + " \n Decrypted value :: " + normalTextDec);
setContentView(txe);
}catch(Exception e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
How can I use my own key?
What is the use of a rawKey?
That's the getRawKey function I've been fighting against for as long as I'm on StackOverflow. To use a password, use PBKDF2, it's build into Java. To create a random key, use a random number generator new SecureRandom() and SecretKeySpec.
If your random number generator ever does anything unexpected, e.g. generating a random number instead of acting as a deterministic PRNG your key will not be the same and you may never decrypt your ciphertext again. This actually happened after an update on Android where the default provider was replaced and the RNG differed from the one before.
package com.example.encryption;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class AESOwnKey {
private Cipher ecipher;
private Cipher dcipher;
AESOwnKey(SecretKey key) {
try {
ecipher = Cipher.getInstance("AES");
dcipher = Cipher.getInstance("AES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
} catch (Exception e) {
System.out.println("Failed in initialization");
}
}
public byte[] encrypt(String str) {
try {
byte[] utf8 = str.getBytes("UTF-8");
byte[] enc = ecipher.doFinal(utf8);
return Base64.getEncoder().encode(enc);
} catch (Exception e) {
System.out.println("Failed in Encryption");
}
return null;
}
public String decrypt(byte[] bytes) {
try {
byte[] dec = Base64.getDecoder().decode(bytes);
byte[] utf8 = dcipher.doFinal(dec);
return new String(utf8, "UTF-8");
} catch (Exception e) {
System.out.println("Failed in Decryption");
}
return null;
}
public static void main(String[] args) {
try {
String mykey = "1234567891234567";
SecretKey key = new SecretKeySpec(mykey.getBytes(), "AES");
AESOwnKey encrypter = new AESOwnKey(key);
String original = "Testing encryption";
System.out.println("Before Encryption : " + original);
byte[] encrypted = encrypter.encrypt(original);
System.out.println("After Encryption : " + encrypted);
String decrypted = encrypter.decrypt(encrypted);
System.out.println("After Decryption : " + decrypted);
} catch (Exception e) {
}
}
}

Encryption / decryption for j2me app with AES 128 encryption using sha256 hashing

I have to use encryption / decryption mechanism for a j2me application and lots of searching I found that Bouncy Castle is most suitable for j2me apps.
Below are the steps that I follow to perform encryption:
Get a string needed to create a hash key using sha256 algorithm;
With that hash key perform AES-128 encryption for a plain text.
Below is the sample code. It is using key and IV (Initialization Vector) for encryption key generation. Is it same as sha256 hashing?
static String strEnc = "String for encryption";
final static String strPassword = "2345678978787878"; // AES 128 -
String encrypted;
public static String strEncResult;
public static String strDcrResult;
public static String keyStr;
String dcrtpt;
String enc1;
//Key key;
/*public static byte[] getSHA256(String key) {
SHA256Digest digester = new SHA256Digest();
byte[] retValue = new byte[digester.getDigestSize()];
digester.update(key.getBytes(), 0, key.length());
digester.doFinal(retValue, 0);
System.out.println("retValue === "+retValue);
return retValue;
}*/
public static byte[] cipherData(PaddedBufferedBlockCipher cipher,
byte[] data) throws Exception {
int minSize = cipher.getOutputSize(data.length);
byte[] outBuf = new byte[minSize];
int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
int length2 = cipher.doFinal(outBuf, length1);
int actualLength = length1 + length2;
byte[] result = new byte[actualLength];
System.arraycopy(outBuf, 0, result, 0, result.length);
return result;
}
public static byte[] decrypt(byte[] cipher, byte[] key, byte[] iv)
throws Exception {
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key),
iv);
aes.init(false, ivAndKey);
return cipherData(aes, cipher);
}
public static byte[] encrypt(byte[] plain, byte[] key, byte[] iv)
throws Exception {
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key),
iv);
aes.init(true, ivAndKey);
return cipherData(aes, plain);
}
public static String encryptMe(String plain){
byte[] plainStr = plain.getBytes();
byte[] keyStr = strPassword.getBytes();//getSHA256(strPassword);
byte[] ivStr = strPassword.getBytes();//getSHA256(strPassword);
try {
byte[] encBytes = encrypt(plainStr, keyStr,
ivStr);
byte[] encbase = Base64.encode(encBytes);
strEncResult = new String(encbase, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return strEncResult;
}
public static String decryptMe(String encrtptedStr){
try {
byte[] dcrByte = Base64.decode(encrtptedStr.getBytes());
byte[] dec = decrypt(dcrByte, strPassword.getBytes()/*getSHA256(strPassword)*/,
strPassword.getBytes()/*getSHA256(strPassword)*/);
strDcrResult = new String(dec, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return strDcrResult;
}
protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException {
}
protected void pauseApp() {
}
protected void startApp() throws MIDletStateChangeException {
byte[] enc;
try {
enc = encrypt(strEnc.getBytes(), /*getSHA256(strPassword)*/strPassword.getBytes(),
/*getSHA256(strPassword)*/strPassword.getBytes());
byte[] encbase = Base64.encode(enc);
encrypted = new String(encbase, "UTF-8");
enc1= encryptMe ("String for encryption");
System.out.println("Encrypted is:" + encbase + "/// "+enc1);
} catch (Exception e) {
e.printStackTrace();
}
byte[] decbase = Base64.decode(encrypted.getBytes());
byte[] dec;
try {
dec = decrypt(decbase, /*getSHA256(strPassword)*/strPassword.getBytes(),
/*getSHA256(strPassword)*/strPassword.getBytes());
dcrtpt = decryptMe(enc1);
System.out.println("Decrypted file is:" + new String(dec, "UTF-8")+"///"+dcrtpt);
} catch (Exception e) {
e.printStackTrace();
}
}
i got it worked!!. i have used sha256 for secret key generation and took first 16 digit for AES 128 encryption. i am getting correct encrypted and decrypted data when it is 16 or below 16 string. if it is above 16 char string i am getting 16 char with some unwanted characters. (Eg: abcdefghijklmnop5#�D�!�&M�\~C��) can anybody help me to sort this issue. please see below for code
public static String getSHA256(String key) {
SHA256Digest digester = new SHA256Digest();
byte[] retValue = new byte[digester.getDigestSize()];
digester.update(key.getBytes(), 0, key.length());
digester.doFinal(retValue,0);
byteToStr = new String(Hex.encode(retValue));
System.out.println("byteToStr === " + byteToStr);
byteToStr = byteToStr.substring(0, 16);
System.out.println("byteToStr after subString === " + byteToStr);
return byteToStr;
}
public static byte[] cipherData(BufferedBlockCipher cipher, byte[] data)
throws Exception {
int minSize = cipher.getOutputSize(data.length);
System.out.println("min Size = "+minSize);
byte[] outBuf = new byte[minSize];
int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
int length2 = cipher.doFinal(outBuf, length1);
System.out.println("length1 = "+length1 +"/ length2 = "+length2);
int actualLength = length1 + length2;
System.out.println("actualLength = "+actualLength);
byte[] result = new byte[actualLength];
System.arraycopy(outBuf, 0, result, 0, result.length);
return result;
}
public static byte[] decrypt(byte[] cipher, byte[] key/* , byte[] iv */)
throws Exception {
/*
* PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher( new
* CBCBlockCipher(new AESEngine())); CipherParameters ivAndKey = new
* ParametersWithIV(new KeyParameter(key), iv); aes.init(false,
* ivAndKey); return cipherData(aes, cipher);
*/
BufferedBlockCipher aes = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
KeyParameter secretKey = new KeyParameter(key);
aes.init(false, secretKey);
return cipherData(aes, cipher);
}
public static byte[] encrypt(byte[] plain, byte[] key/* , byte[] iv */)
throws Exception {
/*
* PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher( new
* CBCBlockCipher(new AESEngine())); CipherParameters ivAndKey = new
* ParametersWithIV(new KeyParameter(key), iv);
*/
BufferedBlockCipher aes = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
KeyParameter secretKey = new KeyParameter(key);
aes.init(true, secretKey);
return cipherData(aes, plain);
}
public static String encryptMe(String plain) {
byte[] plainStr = plain.getBytes();
byte[] keyStr = getSHA256(key).getBytes();
// byte[] ivStr = iv.getBytes();//
System.out.println("key str = "+Strings.fromByteArray(keyStr));
try {
byte[] encBytes = encrypt(plainStr, keyStr/*
* , ivStr
*/);
strEncResult= Base64.toBase64String(encBytes);
//strEncResult = new String(encbase);
} catch (Exception e) {
e.printStackTrace();
}
return strEncResult;
}
public static String decryptMe(String cipherText) {
try {
byte[] dcrByte = Base64.decode(cipherText);
byte[] dec = decrypt(dcrByte, getSHA256(key).getBytes()/*
* ,iv.getBytes
* ()
*/);
strDcrResult = Strings.fromByteArray(dec);
} catch (Exception e) {
e.printStackTrace();
}
return strDcrResult;
}

Resources