Java AES 256 Secure Key Generator -- Illegal key size - java

I am trying to generate a key for encryption:
public static final String ENCYT_ALGORITHM = "AES/ECB/PKCS7Padding";
public static final String KEY_ALGORITHM = "PBEWITHSHA256AND256BITAES-CBC-BC" ;
//BENCYT_ALGORITHMSE64Encoder encod = new BENCYT_ALGORITHMSE64Encoder();
//BENCYT_ALGORITHMSE64Decoder decod = new BENCYT_ALGORITHMSE64Decoder();
public Encryption(String preMaster,String text,int x){
this.preMaster=preMaster;
this.text=text.getBytes();
}
public void keyGenerator(){
KeyGenerator kg = null;
try {
kg = KeyGenerator.getInstance("AES");
secret = kg.generateKey();
} catch (Exception e) {
// TODO ENCYT_ALGORITHMuto-generated catch block
e.printStackTrace();
}
}
public String preMaster() {
byte[] keys = null;
keys = preMaster.getBytes();
int x = -1;
int process = 0;
while (x < keys.length - 2) {
x++;
switch (x) {
case 1:
process = keys[x + 1] | a ^ c & (d | keys[x] % a);
case 2:
process += a | (keys[x] ^ c) & d;
case 3:
process += keys[x] ^ (keys[x + 1] / a) % d ^ b;
default:
process += keys[x + 1] / (keys[x] ^ c | d);
}
}
byte[] xs = new byte[] { (byte) (process >>> 24),
(byte) (process >> 16 & 0xff), (byte) (process >> 8 & 0xff),
(byte) (process & 0xff) };
preMaster = new String(xs);
KeyGenerators key = new KeyGenerators(preMaster);
String toMaster = key.calculateSecurityHash("MD5")
+ key.calculateSecurityHash("MD2")
+ key.calculateSecurityHash("SHA-512");
return toMaster;
}
public String keyWrapper(){
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Key SharedKey = secret;
String key = null;
char[] preMaster = this.preMaster().toCharArray();
try {
byte[]salt={ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
paramSpec = new PBEParameterSpec(salt,256);
PBEKeySpec keySpec = new PBEKeySpec(preMaster,salt,1024,256);
SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
passwordKey = factory.generateSecret(keySpec);
Cipher c = Cipher.getInstance(KEY_ALGORITHM);
c.init(Cipher.WRAP_MODE, passwordKey, paramSpec);
byte[] wrappedKey = c.wrap(SharedKey);
key=new String(wrappedKey,"UTF8");
}catch(Exception e){
e.printStackTrace();
}
return key;
}
And this is the result :
java.security.InvalidKeyException: Illegal key size
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at fiador.authentication.util.Encryption.keyWrapper(Encryption.java:101)
at fiador.authentication.util.Encryption.main(Encryption.java:144)
null
I am really desperate ... please help me, thanks !

You have not installed the unlimited strength crypto files, (the default JDK install allows 128 bit keys as documented in http://download.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppC).
Download unlimited strength crypto package here.
Installation Help

I can't see where keyGenerator is being called. If it is not called, then secret is not being initialized. That could be the cause of the root exception. (It is hard to tell, because you've left out the declaration of secret.)

Related

Java 256-bit AES Encryption

I need to implement 256 bit AES encryption for cash flow i have c# answer but the answer is not the same,for a newbie, I am not sure if my direction is correct.
this is my code
public static void main(String[] args) {
String key = "12345678901234567890123456789012";
String hashIv = "1234567890123456";
String value = "MerchantID=3430112RespondType=JSONTimeStamp=1485232229Version=1.4MerchantOrderNo=S_1485232229Amt=40ItemDesc=UnitTest";
String result = encrypt(key, hashIv, value);
System.out.println(result);
System.out.println();
String sha256 = encrySha256("HashKey=" + key + "&" + result + "&HashIV=" + hashIv);
System.out.println(sha256.trim());
}
public static String encrypt(String hashKey, String hashIv, String text) {
try {
SecretKeySpec skeySpec = new SecretKeySpec(hashKey.getBytes("UTF-8"), "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(hashIv.getBytes("UTF-8"));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
byte[] encrypted = cipher.doFinal((text.getBytes("UTF-8")));
String test = bytesToHex(encrypted);
return test.toLowerCase();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
public static String bytesToHex(byte[] bytes) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
public static String encrySha256(String value) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(value.getBytes());
byte byteBuffer[] = messageDigest.digest();
StringBuffer strHexString = new StringBuffer();
for (int i = 0; i < byteBuffer.length; i++) {
String hex = Integer.toHexString(0xff & byteBuffer[i]);
if (hex.length() == 1) {
strHexString.append('0');
}
strHexString.append(hex);
}
return strHexString.toString().toUpperCase();
} catch (Exception e) {
}
return null;
}
sample encrypt answer :
ff91c8aa01379e4de621a44e5f11f72e4d25bdb1a18242db6cef9ef07d80b0165e476fd1d
9acaa53170272c82d122961e1a0700a7427cfa1cf90db7f6d6593bbc93102a4d4b9b66d9
974c13c31a7ab4bba1d4e0790f0cbbbd7ad64c6d3c8012a601ceaa808bff70f94a8efa5a4f
984b9d41304ffd879612177c622f75f4214fa
encryptSha256 answer : EA0A6CC37F40C1EA5692E7CBB8AE097653DF3E91365E6A9CD7E91312413C7BB8
this is c# code and this is sample data
[MerchantID] => 3430112 [RespondType] => JSON [TimeStamp] => 1485232229
[Version] => 1.4 [MerchantOrderNo] => S_1485232229 [Amt] => 40 [ItemDesc] =>
UnitTest
public string EncryptAES256(string source)//加密
{
string sSecretKey = "12345678901234567890123456789012";
string iv = "1234567890123456";
byte[] sourceBytes =
AddPKCS7Padding(Encoding.UTF8.GetBytes(source), 32);
var aes = new RijndaelManaged();
aes.Key = Encoding.UTF8.GetBytes(sSecretKey);
aes.IV = Encoding.UTF8.GetBytes(iv);
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.None;
ICryptoTransform transform = aes.CreateEncryptor();
return ByteArrayToHex(transform.TransformFinalBlock(sourceBytes, 0,
sourceBytes.Length)).ToLower();
}
private static byte[] AddPKCS7Padding(byte[] data, int iBlockSize)
{
int iLength = data.Length;
byte cPadding = (byte)(iBlockSize - (iLength % iBlockSize));
var output = new byte[iLength + cPadding];
Buffer.BlockCopy(data, 0, output, 0, iLength);
for (var i = iLength; i < output.Length; i++)
output[i] = (byte)cPadding;
return output;
}
private static string ByteArrayToHex(byte[] barray)
{
char[] c = new char[barray.Length * 2];
byte b;
for (int i = 0; i < barray.Length; ++i)
{
b = ((byte)(barray[i] >> 4));
c[i * 2] = (char)(b > 9 ? b + 0x37 : b + 0x30);
b = ((byte)(barray[i] & 0xF));
c[i * 2 + 1] = (char)(b > 9 ? b + 0x37 : b + 0x30);
}
return new string(c);
}
The reason for the different encrypted data is that you compare different plain texts. In your Java code you encrypt the plain text
MerchantID=3430112RespondType=JSONTimeStamp=1485232229Version=1.4MerchantOrderNo=S_1485232229Amt=40ItemDesc=UnitTest
and you compare the encrypted data with your reference data
ff91c8aa01379e4de621a44e5f11f72e4d25bdb1a18242db6cef9ef07d80b0165e476fd1d9acaa53170272c82d122961e1a0700a7427cfa1cf90db7f6d6593bbc93102a4d4b9b66d9974c13c31a7ab4bba1d4e0790f0cbbbd7ad64c6d3c8012a601ceaa808bff70f94a8efa5a4f984b9d41304ffd879612177c622f75f4214fa
However, these reference data correspond to a different plain text. The latter you can easily derive by decrypting the reference data with the C# DecryptAES256-method which provides
MerchantID=3430112&RespondType=JSON&TimeStamp=1485232229&Version=1.4&MerchantOrderNo=S_1485232229&Amt=40&ItemDesc=UnitTest
Here, in contrast to the plain text in your Java code, a &-delimiter is used.
If you use the same plain text the Java encrypt- and the C# EncryptAES256-method provide the same encrypted data (same key, IV and padding supposed; for the latter see EDIT-section).
In the following testcase the plain text from your Java code is used:
encrypt("12345678901234567890123456789012", "1234567890123456", "MerchantID=3430112RespondType=JSONTimeStamp=1485232229Version=1.4MerchantOrderNo=S_1485232229Amt=40ItemDesc=UnitTest")
and
EncryptAES256("MerchantID=3430112RespondType=JSONTimeStamp=1485232229Version=1.4MerchantOrderNo=S_1485232229Amt=40ItemDesc=UnitTest")
both provide the encrypted data:
ff91c8aa01379e4de621a44e5f11f72ef45b7b9f9663d386da51af13f7f3b8f2b1ed4a3b7ac6b7783402193ea1d766e3046b6acf612d62568ccdbc475e5a14d114273735b069464dcc8281f4e5bf8486eb97d31602c3fe79cfe7140d2848413edad9d96fabf54d103f3d7a9b401c83fa5e4f17b10a280df10b3d61f23e69bbb8
which (as expected) differs from your reference data (with the exception of the first block).
EDIT
There is a second issue concerning the padding: Your C# EncryptAES256-method uses a custom padding provided by the C# AddPKCS7Padding-method which pads to a multiple of 32 bytes.
In contrast, your Java encrypt-method uses PKCS5Padding which pads to a multiple of 16 bytes.
Thus, the encrypted data of the Java encrypt- and the C# EncryptAES256-method differ if the length of the plain text is between 16 * n byte and 16 * (n + 1) - 1 byte with even n (0,2,4,...).
For odd n (1,3,5,...) the encrypted data are identical. In the example above the byte array of the plain text has 116 bytes that is n = 7 (112 <= 116 <= 127) and therefore the encrypted data are the same.
If the Java encrypt-method should use the same padding as the C# EncryptAES256-method you additionally have to implement an analogous Java-method e.g.:
private static byte[] addPKCS7Padding(byte[] data, int iBlockSize)
{
int iLength = data.length;
byte cPadding = (byte)(iBlockSize - (iLength % iBlockSize));
byte[] output = new byte[iLength + cPadding];
System.arraycopy(data, 0, output, 0, iLength);
for (int i = iLength; i < output.length; i++)
output[i] = (byte)cPadding;
return output;
}
and in the Java encrypt-method you have to replace:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
with
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
and also
byte[] encrypted = cipher.doFinal(text.getBytes("UTF-8"));
with
byte[] encrypted = cipher.doFinal(addPKCS7Padding(text.getBytes("UTF-8"), 32));
before:
MerchantID=3430112RespondType=JSONTimeStamp=1485232229Version=1.4MerchantOrderNo=S_1485232229Amt=40ItemDesc=UnitTest
After:
MerchantID=3430112&RespondType=JSON&TimeStamp=1485232229&Version=1.4&MerchantOrderNo=S_1485232229&Amt=40&ItemDesc=UnitTest
I only add "&" with each parameter, it's work!!!!
try it!!!
(我只加了&就成功拉,你的代碼沒問題,只是參數要加&而已)

Block by block encryption : decryption not working from second block

I am implementing CBC encryption + decryption block by block by using auto generated key and self defined IV. I am getting problem in second block decryption, decryption for first block is working but its not working for second block. Here is my code.
public static void main(String args[]) {
Cipher fcipher, scipher;
String plaintextstring = "";
System.out.println("Enter the first message:");
BufferedReader buffp = new BufferedReader(new InputStreamReader(System.in));
try {
plaintextstring = buffp.readLine();
} catch (Exception e) {
System.out.println("Exception occured:" + e.getMessage());
}
int strlen1 = plaintextstring.length();
int x1 = strlen1 % 8;
int y1 = 8 - x1;
StringBuffer buf1 = new StringBuffer(plaintextstring);
if (x1 > 0) {
for (int k = 0; k < y1; k++) {
buf1.append('0');
}
}
System.out.println("Modified plaintext is:" + buf1);
String inp = buf1.toString();
try {
SecretKey key1 = KeyGenerator.getInstance("DES").generateKey();
SecretKey key2 = KeyGenerator.getInstance("DES").generateKey();
fcipher = Cipher.getInstance("DES/ECB/NoPadding");//CBC
scipher = Cipher.getInstance("DES/ECB/NoPadding");//CBC
// Create an 8-byte initialization vector
//byte[] iv = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
//byte[] iv = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
byte[] iv = {(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08};
System.out.println("Length of IV is :" + iv.length);
byte[] sencrypted = new byte[8];
fcipher.init(Cipher.ENCRYPT_MODE, key1);
scipher.init(Cipher.DECRYPT_MODE, key2);
System.out.println("Default Charset is :" + Charset.defaultCharset());
byte[] pbytes = inp.getBytes("UTF-8");
System.out.println("Byte array of input string is :" + pbytes);
System.out.println("Size of first message in bytes is:" + pbytes.length);
for (int i = 0; i < pbytes.length; i++) {
System.out.println("Array values of byte array are: " + pbytes[i]);
}
int z = (pbytes.length) / 8;
System.out.println("Number of data blocks of 8 bytes formed from message = " + z);
for (int i = 0; i < z; i++) {
byte[] ds = getSection(pbytes, i * 8);//getting block of 64bit
byte[] out = new byte[8];
for (int r = 0; r < 8; r++) {
System.out.println("Array values of IV from previous stage is :" + iv[r]);
}
for (int k = 0; k < 8; k++) {
out[k] = (byte) (ds[k] ^ iv[k]);//XORing of message block with IV bit by bit.
// System.out.println("XORed array byte by byte is:"+out[k]);
}
byte[] fencrypted = fcipher.doFinal(out);//Applying DES Encryption to the XOR'ed result.(E)key1
byte[] fdecrypted = scipher.doFinal(fencrypted);// (D)key2
sencrypted = fcipher.doFinal(fdecrypted);// (E)key1
System.out.println("Encrypted byte length: " + sencrypted.length);
System.out.println("Encrypted text is :" + sencrypted);
fcipher.init(Cipher.DECRYPT_MODE, key1);
scipher.init(Cipher.ENCRYPT_MODE, key2);
byte[] sfdecrypted = fcipher.doFinal(sencrypted);//DES1 key1 (D)
byte[] sfencrypted = scipher.doFinal(sfdecrypted);//DES Key2 (E)
byte[] ssdecrypted = fcipher.doFinal(sfencrypted);//DES Key3 (D)
System.out.println("length of final decrypted byte array is :" + ssdecrypted.length);
byte[] d = new byte[8];
for (int u = 0; u < 8; u++) {
d[u] = (byte) (ssdecrypted[u] ^ iv[u]);//XORing of message block with IV bit by bit.
System.out.println("final decrypted array byte by byte of a single 64 bit block is:" + d[u]);
}
String sdecryptedstr = new String(d);
System.out.println("Decrypted block is :" + sdecryptedstr);
iv = sencrypted;
System.out.println("IV from previous stage is: "+iv);
}
} catch (Exception e) {
System.out.println("Exception Occured: " + e);
}
}
//function to get CBC message blocks.
public static byte[] getSection(byte[] message, int start) {
byte[] section = new byte[8];//dividing whole message into 64bit blocks.
for (int i = 0, j = start; i < 8; i++, j++) {
section[i] = message[j];
}
return section;
}//end of getSection function.

emulate pbewithmd5anddes in javascript

I made a password generating program some time ago in java.
it generated passwords based on an input string and password.
it used: pbewithMD5andDES
now i'm making a new version of this for mobile devices in javascript.
i found the library crypto-js witch allows me to generate MD5-hashes and encrypt using DES
but i can't seem to generate identical passwords
what am i doing wrong?
java version:
public static String generate(String password, String passphase) throws Exception {
try {
PBEKeySpec pbeKeySpec = new PBEKeySpec(passphase.toCharArray());
PBEParameterSpec pbeParamSpec;
SecretKeyFactory keyFac;
// Salt
byte[] salt = {(byte) 0xc8, (byte) 0x73, (byte) 0x61, (byte) 0x1d, (byte) 0x1a, (byte) 0xf2, (byte) 0xa8, (byte) 0x99};
// Iteration count
int count = 20;
// Create PBE parameter set
pbeParamSpec = new PBEParameterSpec(salt, count);
keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
// Create PBE Cipher
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
// Initialize PBE Cipher with key and parameters
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
// Our cleartext
byte[] cleartext = password.getBytes();
// Encrypt the cleartext
byte[] ciphertext = pbeCipher.doFinal(cleartext);
return byteArrayToHexString(ciphertext).substring(0, 12);
} catch (Exception ex) {
throw new Exception(ex.getMessage());
}
}
public static String byteArrayToHexString(byte[] b){
StringBuilder sb = new StringBuilder(b.length * 2);
for (int i = 0; i < b.length; i++){
int v = b[i] & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase();
}
the new javascript version (not compete): (i tried both orders: first hashing then DES, and the oher way around)
var hashedPassword = CryptoJS.MD5(password);
var encryptedPassword = CryptoJS.DES.encrypt(hashedPassword, passphrase).toString();
var result = encryptedPassword.toString().substring(0, 12).toUpperCase();
am i on the right way?

Getting a padding exception in javax.crypto

I'm trying to code a crypto java testclass which encrypt and decrypt a String password with BouncyCastle. The main() is very simple, I do encryptPass() and then decryptPass(), and I watch the console trace.
The problem is when it tries to decrypt, I got a padding exception :
javax.crypto.BadPaddingException: pad block corrupted
at org.bouncycastle.jce.provider.JCEBlockCipher.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at com.kiengi.crypto.Crypto.decryptPass(Crypto.java:79)
My code is the following for the Crypto class :
// password to be crypted
public String pass = "password_go_here";
// key for encrypt pass
public String passKey = generateRandomKey(); // generation clef 16 caractere [a-zA-Z0-9]
// Encrypted pass
public String cryptedPass;
public final Logger logger = Logger.getLogger(this.getClass());
private final static byte[] IV_BYTES = new byte[] { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
0x00, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
public Crypto() {
super();
}
public void encryptPass(){
Security.addProvider(new BouncyCastleProvider());
IvParameterSpec _ivSpec = new IvParameterSpec(IV_BYTES);
try{
KeyGenerator _keygen = KeyGenerator.getInstance("AES");
_keygen.init(new SecureRandom(passKey.getBytes()));
SecretKey _key = _keygen.generateKey();
logger.trace("Secret key generated");
Cipher _cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
_cipher.init(Cipher.ENCRYPT_MODE, _key, _ivSpec);
cryptedPass = asHex(_cipher.doFinal(pass.getBytes("UTF-8")));
logger.trace("Encrypted pass : "+cryptedPass);
}catch (Exception e) {
logger.warn("encrypt failed");
e.printStackTrace();
}
}
public void decryptPass() {
byte[] _passKey = passKey.getBytes();
byte[] _cryptedPass = hexFromString(cryptedPass);
Security.addProvider(new BouncyCastleProvider());
IvParameterSpec _ivSpec = new IvParameterSpec(IV_BYTES);
try {
KeyGenerator _keygen = KeyGenerator.getInstance("AES");
_keygen.init(new SecureRandom(_passKey));
SecretKey _key = _keygen.generateKey();
logger.trace("Secret key generated");
Cipher _cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
_cipher.init(Cipher.DECRYPT_MODE, _key, _ivSpec);
String _pass = new String(_cipher.doFinal(_cryptedPass), "UTF-8");
logger.trace("Decrypted pass : "+_pass);
} catch (Exception e) {
logger.warn("decrypt failed");
e.printStackTrace();
}
}
private int fromDigit(char ch) {
if ((ch >= '0') && (ch <= '9')) {
return ch - '0';
} else if ((ch >= 'A') && (ch <= 'F')) {
return ch + 10 - 'A';
} else if ((ch >= 'a') && (ch <= 'f')) {
return ch + 10 - 'a';
} else {
throw new IllegalArgumentException(String.format(
"Invalid hex character 0x%04x", 0xff & ch));
}
}
private byte[] hexFromString(String hex) {
final byte[] buf = new byte[hex.length() / 2];
for (int i = 0, j = 0; i < hex.length(); i += 2) {
buf[j++] = (byte) (fromDigit(hex.charAt(i)) << 4 | fromDigit(hex
.charAt(i + 1)));
}
return buf;
}
private static String asHex(byte buf[]) {
final Formatter formatter = new Formatter(new StringBuffer());
for (int i = 0; i < buf.length; i++) {
formatter.format("%02x", 0xff & buf[i]);
}
return formatter.toString();
}
private String generateRandomKey() {
String _chars = "abcdefABCDEF1234567890";
StringBuffer _pass = new StringBuffer();
for (int x = 0; x < 32; x++) {
int i = (int) Math.floor(Math.random() * (_chars.length() - 1));
_pass.append(_chars.charAt(i));
}
return _pass.toString();
}
Does anyone knows what this exception means?
This code has a bug. It assumes that new SecureRandom(passKey.getBytes()) will initialize the SecureRandom instance with only the bytes supplied in the constructor. This is wrong. The data in the constructor will supplement whatever entropy sources SecureRandom uses, not replace them.
You need to use a proper password-based encryption (PBE) scheme.
This exception means that padding block is corrupted. You use PKCS#7 padding with 16B blocks. In this sample your output is 16B too. So it always should be added block with 16 bytes of value 0x10.
The padding is corrupted because the decryption is corrupted. Your SecureRandom implementation adds its own entropy and generates wrong decryption key. This SecureRandom constructor uses the first PRNG algorithm of the first provider that has registered a SecureRandom implementation.

BOUNCY CAStLE AES 256 decryption problem in java

Really a buggy question , hee is the code:
import java.io.IOException;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class Encryption {
public static final int a = 0x9F224;
public static final int b = 0x98C36;
public static final int c = 0x776a2;
public static final int d = 0x87667;
private String preMaster;
IvParameterSpec ivSpec = new IvParameterSpec(new byte[] { 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01 });
private byte[] text;
private SecretKey secret;
private byte[] sKey;
protected SecretKey passwordKey;
protected PBEParameterSpec paramSpec;
public static final String ENCYT_ALGORITHM = "AES/CBC/PKCS7Padding";
public static final String KEY_ALGORITHM = "PBEWITHSHA256AND256BITAES-CBC-BC" ;
//BENCYT_ALGORITHMSE64Encoder encod = new BENCYT_ALGORITHMSE64Encoder();
//BENCYT_ALGORITHMSE64Decoder decod = new BENCYT_ALGORITHMSE64Decoder();
public Encryption(String preMaster,String text,int x){
this.preMaster=preMaster;
this.text=Encoder.decode(text.toCharArray());
try {
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(256);
secret = kg.generateKey();
} catch (Exception e) {
// TODO ENCYT_ALGORITHMuto-generated catch block
e.printStackTrace();
}
}
public Encryption(String key,String text){
try {
this.text = Encoder.decode(text.toCharArray());
this.sKey = Encoder.decode(key.toCharArray());
} catch (Exception e) {
e.printStackTrace();
}
}
public String preMaster() {
byte[] keys = null;
keys = preMaster.getBytes();
int x = -1;
int process = 0;
while (x < keys.length - 2) {
x++;
switch (x) {
case 1:
process = keys[x + 1] | a ^ c & (d | keys[x] % a);
case 2:
process += a | (keys[x] ^ c) & d;
case 3:
process += keys[x] ^ (keys[x + 1] / a) % d ^ b;
default:
process += keys[x + 1] / (keys[x] ^ c | d);
}
}
byte[] xs = new byte[] { (byte) (process >>> 24),
(byte) (process >> 16 & 0xff), (byte) (process >> 8 & 0xff),
(byte) (process & 0xff) };
preMaster = new String(xs);
KeyGenerators key = new KeyGenerators(preMaster);
String toMaster = key.calculateSecurityHash("MD5")
+ key.calculateSecurityHash("MD2")
+ key.calculateSecurityHash("SHA-512");
return toMaster;
}
public String keyWrapper(){
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Key SharedKey = secret;
String key = null;
char[] preMaster = this.preMaster().toCharArray();
try {
byte[]salt={ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
paramSpec = new PBEParameterSpec(salt,20);
PBEKeySpec keySpec = new PBEKeySpec(preMaster);
SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
passwordKey = factory.generateSecret(keySpec);
Cipher c = Cipher.getInstance(KEY_ALGORITHM);
c.init(Cipher.WRAP_MODE, passwordKey, paramSpec);
byte[] wrappedKey = c.wrap(SharedKey);
key=Encoder.encode(wrappedKey);
}catch(Exception e){
e.printStackTrace();
}
return key;
}
public Key KeyUnwrapper(){
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] wrappedKey = sKey;
Key unWrapped = null;
try{
Cipher c = Cipher.getInstance(KEY_ALGORITHM,"BC");
c.init(Cipher.UNWRAP_MODE, passwordKey, paramSpec);
unWrapped = c.unwrap(wrappedKey, ENCYT_ALGORITHM, Cipher.SECRET_KEY);
}catch(Exception e){
e.printStackTrace();
}
return unWrapped;
}
public String encrypt(){
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
SecretKey key = secret;
String result=null;
try{
Cipher cipher = Cipher.getInstance(ENCYT_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
result =Encoder.encode(cipher.doFinal(text));
}catch(Exception e){
e.printStackTrace();
}
return result;
}
public String decrypt(){
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
String result = null;
SecretKey key = (SecretKey) KeyUnwrapper();
try{
Cipher cipher = Cipher.getInstance(ENCYT_ALGORITHM, "BC");
cipher.init(Cipher.DECRYPT_MODE, key);
result = Encoder.encode(cipher.doFinal(text));
}catch(Exception e){
e.printStackTrace();
}
return result;
}
public static void main(String[] args) throws IOException{
Encryption en = new Encryption("123456","Hello World",0);
String enText = en.encrypt();
String key = en.keyWrapper();
System.out.println(key);
System.out.println(enText);
Encryption de = new Encryption(key,enText);
String plainText = de.decrypt();
System.out.println(plainText);
}
And , this is the result ... i tried all the combinations i can, but none of them works ..
F63DE3EE8CEECF4DF76836CA6D69A3903BD87B5726656C54C1C8EC30B6653B2C0E5C7672BE3CF4BE7B2DC7AC5D07DEA0
F1C8D92E5F74019C569D54D70045ADD6
java.lang.NullPointerException
at org.bouncycastle.jce.provider.JCEBlockCipher.engineInit(Unknown Source)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at fiador.authentication.util.Encryption.KeyUnwrapper(Encryption.java:114)
at fiador.authentication.util.Encryption.decrypt(Encryption.java:142)
at fiador.authentication.util.Encryption.main(Encryption.java:160)
java.lang.NullPointerException
at org.bouncycastle.jce.provider.JCEBlockCipher.engineInit(Unknown Source)
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at fiador.authentication.util.Encryption.decrypt(Encryption.java:145)
at fiador.authentication.util.Encryption.main(Encryption.java:160)
null
The first NullPointerException occurs inside this method call (in the KeyUnwrapper method):
c.init(Cipher.UNWRAP_MODE, passwordKey, paramSpec);
Have a look: Could one of these arguments be null?
Looking at the code, it seems like passwordKey is only assigned to in keyWrapper, but this is not called on this instance of your class.

Categories