How to encrypt and decrypt URl parameter in java without having the html characters like '/,&,=?'
import java.io.UnsupportedEncodingException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public class DesEncrypter {
Cipher ecipher;
Cipher dcipher;
byte[] salt = {
(byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
(byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
};
int iterationCount = 3;
public DesEncrypter(String passPhrase) {
try{
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
ecipher = Cipher.getInstance(key.getAlgorithm());
dcipher = Cipher.getInstance(key.getAlgorithm());
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (java.security.InvalidAlgorithmParameterException e){
} catch (java.security.spec.InvalidKeySpecException e){
} catch (javax.crypto.NoSuchPaddingException e){
} catch (java.security.NoSuchAlgorithmException e){
} catch (java.security.InvalidKeyException e){
}
}
public String encrypt(String str){
try{
byte[] utf8 = str.getBytes("UTF8");
byte[] enc = ecipher.doFinal(utf8);
return new sun.misc.BASE64Encoder().encode(enc);
} catch (javax.crypto.BadPaddingException e){
} catch (IllegalBlockSizeException e){
} catch (UnsupportedEncodingException e){
}
return null;
}
public String decrypt(String str){
try{
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
byte[] utf8 = dcipher.doFinal(dec);
return new String(utf8,"UTF8");
} catch (javax.crypto.BadPaddingException e){
} catch (IllegalBlockSizeException e){
} catch (UnsupportedEncodingException e){
} catch (java.io.IOException e){
}
return null;
}
}
My Code is as above and i am getting encrypted result:6puu4YjzScxHsv9tI/N92g==
In the above output due to backslash i am getting the error that i want to avoid.
Instead of
byte[] utf8 = str.getBytes("UTF8");
byte[] enc = ecipher.doFinal(utf8);
return new sun.misc.BASE64Encoder().encode(enc);
Use Apache Commons URL Safe 64 bit encoder to encode after encryption.
Base64.encodeBase64URLSafeString(enc);
To decode before descryption:
Base64.decodeBase64(dec)
Please Note this is ENCODER not encryptor. But the String is URL safe.
Ideally, you should always Encode your URL using URL Encoder which will ensure that special characters are encoded. So, even if you are having a URL with restricted characters, it will be safe.
Related
Requirements:
Encrypt string using AES Encryption(with GCMParameterSpec and nonce).
Append nonce to Encrypted String to use it later for decryption.
Decrypt string by extracting nonce and the string to decrypt.
I have written the code to encrypt and decrypt the string as required but i am facing "Error while decrypting Tag mismatch!"
Could someone please help me identify the problem. Thanks!
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AES {
private static SecretKeySpec secretKey;
private static byte[] key;
private static final String ENCODING_TYPE = "UTF-8";
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION_VALUE = "AES/GCM/NoPadding";
public static void setKey(String myKey, String hashingType) {
MessageDigest sha = null;
try {
key = myKey.getBytes(ENCODING_TYPE);
sha = MessageDigest.getInstance(hashingType);
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
secretKey = new SecretKeySpec(key, ALGORITHM);
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException "+e.getMessage());
} catch (UnsupportedEncodingException e) {
System.out.println("UnsupportedEncodingException "+e.getMessage());
} catch (Exception e) {
System.out.println("Exception Occured! "+e.getMessage());
}
}
public static String encrypt(String strToEncrypt, String secret, String hashingType) {
String encryptedString = null;
try {
byte[] nonce = new byte[12];
setKey(secret,hashingType);
SecureRandom random = SecureRandom.getInstanceStrong();
random.nextBytes(nonce);
final Cipher encryptCipher = Cipher.getInstance(TRANSFORMATION_VALUE);
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(16 * 8, nonce));
byte[] cipheredString = encryptCipher.doFinal(strToEncrypt.getBytes());
ByteBuffer byteBuffer = ByteBuffer.allocate(nonce.length + cipheredString.length);
byteBuffer.put(nonce);
byteBuffer.put(cipheredString);
encryptedString = Base64.getEncoder().encodeToString(byteBuffer.array()); //Encoding the ByteArrayOutputStream result object to Base64 format
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException "+e.getMessage());
} catch (Exception e) {
System.out.println("Error while encrypting "+e.getMessage());
}
return encryptedString;
}
public static String decrypt(String strToDecrypt, String secret, String hashingType) {
String decryptedString = null;
try {
byte[] nonce = new byte[12];
setKey(secret,hashingType);
final Cipher decryptCipher = Cipher.getInstance(TRANSFORMATION_VALUE);
ByteBuffer byteBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(strToDecrypt));
byteBuffer.get(nonce);
byte[] cipheredString = new byte[byteBuffer.remaining()];
byteBuffer.get(cipheredString);
decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(16 * 8, nonce));
decryptedString = new String(decryptCipher.doFinal(cipheredString));
} catch (Exception e) {
System.out.println("Error while decrypting "+e.getMessage());
}
return decryptedString;
}
}
public class TestAESEncrypt {
public static void main(String[] args) {
final String secretKey = "NEWTEST#Key123";
String originalString = "Gamer_123.aa01#gmail.com";
String encryptedString = AESEncryption.encrypt(originalString, secretKey, "SHA-256");
System.out.println("String to Encrypt : "+originalString);
System.out.println("Encrypted String : "+encryptedString);
}
}
public class TestAESDecryption {
public static void main(String[] args) {
final String secretKey = "NEWTEST#Key123";
String encryptedData = "ey4E+5zNPx4WLx5q0Srf7d1TN/sAzsdYuVmnihXQoA/yoYoxAO/ygrtuh+Zr9rZQ"; //Paste the encrypted string here
String decryptedString = AESEncryption.decrypt(encryptedData, secretKey, "SHA-256") ;
System.out.println("Encrypted String : "+encryptedData);
System.out.println("Decrypted String: "+decryptedString);
}
}
This will never work:
encryptedString = new String(cipher.doFinal(strToEncrypt.getBytes())); //Creating a ciphered string
encryptedString += new String(nonce); //Appending nonce to the encrypted string
encryptedString = new String(Base64.getEncoder().encode(encryptedString.getBytes())); //Encoding ciphered string to Base64 format
Once you attempt to convert the raw bytes to a string you have likely corrupted the data. Base64 encoding it afterward will not save you. Instead, you must do something like:
ByteArrayOutputStream result = new ByteArrayOutputStream();
result.write(nonce);
result.write(cipher.doFinal(strToEncrypt.getBytes()));
String encryptedString = Base64.getEncoder().encodeToString(result.toByteArray());
Also, I noticed your nonce is only 8 bytes. That's probably too short, you should make it 12 bytes.
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AES {
private static SecretKeySpec secretKey;
private static byte[] key;
private static final String ENCODING_TYPE = "UTF-8";
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION_VALUE = "AES/GCM/NoPadding";
public static void setKey(String myKey, String hashingType) {
MessageDigest sha = null;
try {
key = myKey.getBytes(ENCODING_TYPE);
sha = MessageDigest.getInstance(hashingType);
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
secretKey = new SecretKeySpec(key, ALGORITHM);
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException "+e.getMessage());
} catch (UnsupportedEncodingException e) {
System.out.println("UnsupportedEncodingException "+e.getMessage());
} catch (Exception e) {
System.out.println("Exception Occured! "+e.getMessage());
}
}
public static String encrypt(String strToEncrypt, String secret, String hashingType) {
String encryptedString = null;
try {
byte[] nonce = new byte[12];
setKey(secret,hashingType);
SecureRandom random = SecureRandom.getInstanceStrong();
random.nextBytes(nonce);
final Cipher encryptCipher = Cipher.getInstance(TRANSFORMATION_VALUE);
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(16 * 8, nonce));
byte[] cipheredString = encryptCipher.doFinal(strToEncrypt.getBytes());
ByteBuffer byteBuffer = ByteBuffer.allocate(nonce.length + cipheredString.length);
byteBuffer.put(nonce);
byteBuffer.put(cipheredString);
encryptedString = Base64.getEncoder().encodeToString(byteBuffer.array()); //Encoding the ByteArrayOutputStream result object to Base64 format
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException "+e.getMessage());
} catch (Exception e) {
System.out.println("Error while encrypting "+e.getMessage());
}
return encryptedString;
}
public static String decrypt(String strToDecrypt, String secret, String hashingType) {
String decryptedString = null;
try {
byte[] nonce = new byte[12];
setKey(secret,hashingType);
final Cipher decryptCipher = Cipher.getInstance(TRANSFORMATION_VALUE);
ByteBuffer byteBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(strToDecrypt));
byteBuffer.get(nonce);
byte[] cipheredString = new byte[byteBuffer.remaining()];
byteBuffer.get(cipheredString);
decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(16 * 8, nonce));
decryptedString = new String(decryptCipher.doFinal(cipheredString));
} catch (Exception e) {
System.out.println("Error while decrypting "+e.getMessage());
}
return decryptedString;
}
}
When I encrypt the password !QAZxdr5 by the code below:
public static String encryptPassword(String msg) {
try {
KeySpec keySpec = new DESKeySpec(msg.getBytes());
SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(keySpec);
Cipher ecipher = Cipher.getInstance(key.getAlgorithm());
ecipher.init(Cipher.ENCRYPT_MODE, key);
//Encode the string into bytes using utf-8
byte[] utf8 = msg.getBytes("UTF8");
//Encrypt
byte[] enc = ecipher.doFinal(utf8);
//Encode bytes to base64 to get a string
return new String(Base64.getEncoder().encode(enc));
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
I got the output: QQiu2a4NT9YfDAtmHjbk1A==
Now I try to create the decryption for this:
public static String decrypt(String msg) {
try {
KeySpec keySpec = new DESKeySpec(msg.getBytes());
SecretKey key =
SecretKeyFactory.getInstance("DES").generateSecret(keySpec);
Cipher decipher = Cipher.getInstance(key.getAlgorithm());
decipher.init(Cipher.DECRYPT_MODE, key);
// Decode base64 to get bytes
byte[] dec = Base64.getDecoder().decode(msg.getBytes("UTF-8"));
//Decrypt
byte[] utf8 = decipher.doFinal(dec);
//Decode using utf-8
return new String(utf8, "UTF8");
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
However, it doesn't work properly as it returned null :(. Can you please help to check where I'm wrong?
Normally, Base64 encoding of !QAZxdr5 is IVFBWnhkcjU=, however, your code uses a key to encode extra AFAI understand, that's why you get QQiu2a4NT9YfDAtmHjbk1A==. So, decrypt() method needs to know also the key generated already, nonetheless, yours wouldn't.
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Base64;
class EncryptDecryptTest {
public static void main(String[] args) throws Exception {
String key = "it's our key ~~~where is my +1 karma ??~~~ - soner";
String ciphertext = encrypt(key, "!QAZxdr5");
String decrypted = decrypt(key, ciphertext.trim());
String encrypted = encrypt(key, decrypted.trim());
if (ciphertext.contentEquals(encrypted.trim())) {
System.out.println("decrypted!");
} else {
System.out.println("wrong key!");
}
}
public static String encrypt(String key, String data)
throws GeneralSecurityException {
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(StandardCharsets.UTF_8));
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return Base64.getEncoder().encodeToString(cipher.doFinal(dataBytes));
}
public static String decrypt(String key, String data)
throws GeneralSecurityException {
byte[] dataBytes = Base64.getDecoder().decode(data);
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(StandardCharsets.UTF_8));
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] dataBytesDecrypted = (cipher.doFinal(dataBytes));
return new String(dataBytesDecrypted);
}
}
As a side note,
The fact that return new String(Base64.getEncoder().encode(enc)); uses toString() method of array
should be return Base64.getEncoder().encodeToString(enc); in order to get expected encoded datum.
In DES encryption, it uses the same key to encrypt and decrypt a message.
So for both operations you need to have the same key.
In your case, you have used the same string as the key and as the password.
public static String encryptPassword(String msg) {
try {
KeySpec keySpec = new DESKeySpec(msg.getBytes());
In above code segment when creating new DESKeySpec object, you need to pass the key as well.
public static String decrypt(String msg) {
try {
KeySpec keySpec = new DESKeySpec(msg.getBytes());
Even in above decypt method you have to pass the same key you have used in encrypt method.
But in this you have given the encoded string to generate the key.
That is where you have gone wrong.
So i suggest you to change the methods parameters by adding one more parameter as key and then pass the same value for key in both methods.
public static String encryptPassword(String msg, String keySp) {
try {
KeySpec keySpec = new DESKeySpec(keySp.getBytes());
}
public static String decrypt(String msg, String keySp) {
try {
KeySpec keySpec = new DESKeySpec(keySp.getBytes());
}
I have included only the lines that needed to be changed.
You can call those methods by,
String key = "!QAZxdr5";
String password = "!QAZxdr5";
String encriptedPassword = encryptPassword(password, key);
System.out.println(decrypt(encriptedPassword, key));
I am using below code for encryption & decryption in Spring boot project with conveter annotation on attributes which I want to encrypt & decrypt
import org.apache.commons.codec.binary.Base64;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
#Converter
public class CryptoConverter implements AttributeConverter<String, String> {
#Override
public String convertToDatabaseColumn(String attribute) {
if(attribute == null){
return null;
}
try {
byte[] ivBytes;
//String password="Hello";
String password = EncryptionUtil.key.get();
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);
byte[] saltBytes = bytes;
// Derive the key
SecretKeyFactory factory = null;
factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(),saltBytes,65556,256);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
//encrypting the word
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] encryptedTextBytes = cipher.doFinal(attribute.getBytes("UTF-8"));
//prepend salt and vi
byte[] buffer = new byte[saltBytes.length + ivBytes.length + encryptedTextBytes.length];
System.arraycopy(saltBytes, 0, buffer, 0, saltBytes.length);
System.arraycopy(ivBytes, 0, buffer, saltBytes.length, ivBytes.length);
System.arraycopy(encryptedTextBytes, 0, buffer, saltBytes.length + ivBytes.length, encryptedTextBytes.length);
return new Base64().encodeToString(buffer);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (InvalidParameterSpecException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
#Override
public String convertToEntityAttribute(String dbData) {
if(dbData == null){
return null;
}
try {
String password = EncryptionUtil.key.get();
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//strip off the salt and iv
ByteBuffer buffer = ByteBuffer.wrap(new Base64().decode(dbData));
byte[] saltBytes = new byte[20];
buffer.get(saltBytes, 0, saltBytes.length);
byte[] ivBytes1 = new byte[cipher.getBlockSize()];
buffer.get(ivBytes1, 0, ivBytes1.length);
byte[] encryptedTextBytes = new byte[buffer.capacity() - saltBytes.length - ivBytes1.length];
buffer.get(encryptedTextBytes);
// Deriving the key
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, 65556, 256);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes1));
byte[] decryptedTextBytes = null;
decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
return new String(decryptedTextBytes);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return null;
}
}
The issue is this code takes a lot of time to encrypt & decrypt.
With this I am getting a serious performance hit.
If you want to encrypt faster than simply use an actual randomly generated key instead of a password. You can store that in a KeyStore instance that you protect with a password if you like.
You could also simply move the PBKDF2 key derivation out of the encryption method itself and store the resulting SecretKey instance in a field if and only if the password doesn't change in between calls. That way you only have to derive the key once.
PBKDF2 currently uses 65556 iterations each time you want to encrypt/decrypt anything. And PBKDF2 consists of a single hash - in this case SHA-1 - taking 64 bytes at a time. So even before you start encrypting you've hashed at least 65556 (or 64Ki + 20 for some reason) times 64 bytes. That's 4 MiB of hashing you're doing before starting to encrypt. Compared to that you won't even notice the AES encryption.
I'm trying to convert JAVA Code into Objective - C language. I have a requirement where I should Use the same code that Android developers are using. Code follows as
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class EncDec {
public static void main(String args[])
{
String reqMessage="{\"accountType\":\"ALL\",\"uId\":\"c8ff46be-a083-4009-8a33-fc2d22cc40e3|123456784\",\"deviceId\":\"qvxy1234\"}";
Map requestMap=new HashMap();
requestMap.put("body", reqMessage);
String bodyString=(String) requestMap.get("body");
String authKey="M/98hZivBqJQftMHsPvMgg&&";
String encString= encode(authKey,bodyString);
System.out.println("encString ::: "+ encString);
String decString= decode(authKey,encString);
System.out.println("decString ::: "+ decString);
}
public static String encode(String keyString, String stringToEncode) throws NullPointerException {
if (keyString.length() == 0 || keyString == null) {
throw new NullPointerException("Please give Password");
}
if (stringToEncode.length() == 0 || stringToEncode == null) {
throw new NullPointerException("Please give text");
}
try {
SecretKeySpec skeySpec = getKey(keyString);
byte[] clearText = stringToEncode.getBytes("UTF8");
// IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
final byte[] iv = new byte[16];
Arrays.fill(iv, (byte) 0x00);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Cipher is not thread safe
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
byte[] encryptedByte=cipher.doFinal(clearText);
String encrypedValue = new String(Base64.encodeBase64(encryptedByte));
System.out.println("Encrypted: " + stringToEncode + " -> " + encrypedValue);
return encrypedValue;
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return "";
}
/**
* Decodes a String using AES-128 and Base64
*
* #param context
* #param password
* #param text
* #return desoded String
*/
public static String decode(String password, String text) throws NullPointerException {
if (password.length() == 0 || password == null) {
throw new NullPointerException("Please give Password");
}
if (text.length() == 0 || text == null) {
throw new NullPointerException("Please give text");
}
try {
SecretKey key = getKey(password);
// IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
final byte[] iv = new byte[16];
Arrays.fill(iv, (byte) 0x00);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
byte[] encrypedPwdBytes = Base64.decodeBase64(text.getBytes());
// cipher is not thread safe
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
byte[] decrypedValueBytes = (cipher.doFinal(encrypedPwdBytes));
String decrypedValue = new String(decrypedValueBytes);
System.out.println("Decrypted: " + text + " -> " + decrypedValue);
return decrypedValue;
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return "";
}
/**
* Generates a SecretKeySpec for given password
*
* #param password
* #return SecretKeySpec
* #throws UnsupportedEncodingException
*/
private static SecretKeySpec getKey(String password) throws UnsupportedEncodingException {
// You can change it to 256 if you wish
int keyLength = 128;
byte[] keyBytes = new byte[keyLength / 8];
// explicitly fill with zeros
Arrays.fill(keyBytes, (byte) 0x0);
// if password is shorter then key length, it will be zero-padded
// to key length
byte[] passwordBytes = password.getBytes("UTF-8");
int length = passwordBytes.length < keyBytes.length ? passwordBytes.length : keyBytes.length;
System.arraycopy(passwordBytes, 0, keyBytes, 0, length);
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
return key;
}
}
So I want this to be converted in to Objective C. I don't know how to do this. Help me out in this !!
I have searched some code in JAVA And I tried of doing it. But the problem is it will give some other decrypted data but not the exact one that gives using this code. So If I convert the same thing I may get the exact code I guess.
People might be knowing JAVA as well as Objective c here. Those people can help me i guess.
I'm not sure, but you can try it :).
For the encode phase :
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Cipher is not thread safe
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
byte[] encryptedByte=cipher.doFinal(clearText);
String encrypedValue = new String(Base64.encodeBase64(encryptedByte));
Using CCCrypt in Obj-C :
CCCryptorStatus CCCrypt(
CCOperation op, //is kCCEncrypt in your case
CCAlgorithm alg, //is kCCAlgorithmAES128
CCOptions options, //is kCCModeCBC
const void *key, //may be skeySpec
size_t keyLength,
const void *iv, // is your iv key : ivParameterSpec
const void *dataIn,
size_t dataInLength,
void *dataOut, /* data RETURNED here */
size_t dataOutAvailable,
size_t *dataOutMoved)
__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);
Please reference : CCCrypt decrypting in AES CBC works even without IV
for more information, Hope this help you.
Hey I got the answer go through these links below you will get the exact code for Android and IOS...
https://gist.github.com/m1entus/f70d4d1465b90d9ee024
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I have a program that encrypts and decrypts using the AES algorithm, but I have to specify the name of the encrypted file, and also specify the format of the original file as part of the name of the encrypted file. I will like to know how how to implement the following features into my code:
I want the name of the encrypted file to be in cipherText
I want the computer to be able to decide the file type(extension eg.txt) without me having to specify it, for example in my code if I am encrypting a .jpg file, I have to specify the name of the encrypted file as encrypt.jpg
Here is my code which i have tried to implement:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Scanner;
public class EncryptDecrypt {
static Cipher cipher;
static byte[] cipherText;
static byte[] input;
static byte k[]="2305ty6345663ty0".getBytes();
static SecretKeySpec key = new SecretKeySpec(k, "AES");
static int ctLength;
static String filePath = "C:/inddexfolder/casie.jpg";
static String encryptionPath = "C:/indexfolder1/encrypt.jpg";
public static void main(String[] args) {
EncryptDecrypt.encrypt();
EncryptDecrypt.decrypt();
}
public static void encrypt() {
try{
input = filePath.getBytes();
FileInputStream file = new FileInputStream(filePath);
FileOutputStream outStream = new FileOutputStream(encryptionPath);
cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = new byte[cipher.getOutputSize(input.length)];
ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength+= cipher.doFinal(cipherText, ctLength);
String encrypted = new String (cipherText);
CipherOutputStream cos = new CipherOutputStream(outStream, cipher);
byte[] buf = new byte[1024];
int read;
while((read=file.read(buf))!=-1){
cos.write(buf,0,read);
}
file.close();
outStream.flush();
cos.close();
}
catch(IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (ShortBufferException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
}
public static void decrypt() {
try {
FileInputStream file = new FileInputStream(encryptionPath);
FileOutputStream outStream = new FileOutputStream("casenc1.jpg");
byte k[]="2305ty6345663ty0".getBytes();
SecretKeySpec key = new SecretKeySpec(k, "AES");
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
CipherOutputStream cos = new CipherOutputStream(outStream, cipher);
byte[] buf = new byte[1024];
int read;
while((read=file.read(buf))!=-1) {
cos.write(buf,0,read);
}
file.close();
outStream.flush();
cos.close();
Runtime.getRuntime().exec("rundll32 url.dll, FiProtocolHandler
"+"casenc1.jpg");
} catch(IOException e) {
System.out.println(" not decrypted Successfully");
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
}
For the FileOutputStream in the encrypt method , i tried:
FileOutputStream outStream
= new FileOutputStream(encryptionPath = new String(cipherText));
…to see if I could get the file name to be in cipher text but I got these errors:
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.<init>(Unknown Source)
at EncryptDecrypt.encrypt(EncryptDecrypt.java:48)
at EncryptDecrypt.main(EncryptDecrypt.java:37)
Thanks!
Your cipherText is null. Please check whether you try assign it before encrypt it.
FileOutputStream outStream
= new FileOutputStream(encryptionPath = new String(cipherText));