Android - Encrypt and decrypt data using fingerprint authentication - android

I'm facing problem from 3 days. I need to save a text from EditText into SharedPreferences. This text should be saved encrypted in SharedPreference after user authenticated with fingerprint scanner. Then I need to decrypt, later, this data so I need a permanent storage mechanism for the SecretKey generated.
private SecretKey createKey(String keyName) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
keyGenerator.init(new KeyGenParameterSpec.Builder(keyName,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setKeySize(DEFAULT_KEY_SIZE)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build());
return keyGenerator.generateKey();
}
Problem is happen when I try to load KeyStore from file using FileInputStream:
public static SecretKey getKeyFromKeystore(Context context) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
FileInputStream fis = null;
try {
fis = context.openFileInput(KEYSTORE_FILENAME);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
// FileInputStream fis = context.openFileInput(KEYSTORE_FILENAME);
keyStore.load(fis, null);
SecretKey keyStoreKey = null;
try {
keyStoreKey = (SecretKey) keyStore.getKey(CONFIDENTIALITY_KEY, null);
} catch (KeyStoreException e) {
e.printStackTrace();
return null;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
return null;
}
return keyStoreKey;
}
I'm getting error:
java.lang.IllegalArgumentException: InputStream not supported
at
android.security.keystore.AndroidKeyStoreSpi.engineLoad(AndroidKeyStoreSpi.java:930)
Without .setUserAuthenticationRequired(true) I don't have this problem but I don't think this is the right way to use fingerprint's security.

Android Keystore's storage is located outside of your app's process. Thus, you don't need to store it into or load it from a file. All you need to do is invoke keyStore.load(null) and you should be good to go.

Use RxFingerprint may be it solve your problem. Also Read This

Related

Key user not authenticated when using a SecretKey directly as loaded from keystore

I'm trying to encrypt data use Cipher with SecretKey loaded in KeyStore but always got this error :
Caused by: android.security.KeyStoreException: Key user not authenticated
I tried creating SecretKeySpec myself it worked. I'm using android Q to test.
Can anyone help me explain the problem?
My code
public Cipher createCipher() {
Cipher cipher;
try {
cipher = Cipher.getInstance(
KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new RuntimeException("Failed to get Cipher", e);
}
return cipher;
}
public boolean initCipher() {
try {
cipher = createCipher();
SecretKey key = KeyStoreTools.getSecretKey(KEY_NAME);
cipher.init(Cipher.ENCRYPT_MODE, key);
return true;
} catch (KeyPermanentlyInvalidatedException e) {
KeyStoreTools.removeAlias(KEY_NAME);
return false;
} catch (Throwable e) {
throw new RuntimeException("Failed to init Cipher", e);
}
}
public static SecretKey getSecretKey(String keyName) {
Key key = getKey(keyName);
if (!keyExists(key)) {
key = generateKey(keyName);
}
return (SecretKey) key;
}
public static SecretKey generateKey(String keyName) {
SecretKey secretKey = null;
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(keyName,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT);
builder.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_PKCS7);
keyGenerator.init(builder.build());
secretKey = keyGenerator.generateKey();
} catch (NoSuchAlgorithmException | NoSuchProviderException exc) {
exc.printStackTrace();
} catch (Throwable e) {
throw new RuntimeException("Failed to generateKey", e);
}
return secretKey;
}
public String encrypt(Cipher cipher, byte[] dataToEncrypt) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(dataToEncrypt);
byte[] enc = cipher.doFinal(md.digest());
String base64 = Base64.encodeToString(enc, Base64.DEFAULT);
return base64;
} catch (BadPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException e ) {
e.printStackTrace();
}
return "";
}
My issue throw because :
I encrypt using the cipher before the key has been flagged for successful user authentication. So move encrypt in onAuthenticationSucceeded and it's worked.
Hope my answer will help someone else.

Encrypt and save in external storage the String response of Json as a textfile

I am new in Text file Encryption in Android. And tried so many example of text encryption but i am so confused how to apply.
I have 5 string records from json response and i want to save them in a text file(in External Storage) and in "Encrypted format" . I've tried code of cipher_text_encoding but really confused with lots of classes in it.
Please suggest me either good tutorial for text encryption or give me hint how to encode.
Thanks in advance.
Encryption and Decryption using AES Secret Key Algorithm
Generate AES Secret Key:
public static byte[] generateAesSecretKey(){
String SALT2 = "strong_salt_value";
String username = "user_name";
String password = "strong_password";
byte[] key = (SALT2 + username + password).getBytes();
SecretKey secretKeySpec = null;
try {
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
secretKeySpec = new SecretKeySpec(key, "AES");
} catch (Exception e) {
e.printStackTrace();
}
return secretKeySpec.getEncoded();
}
Encryption:
public static byte[] encodeFile(byte[] secretKey, byte[] fileData) {
SecretKeySpec skeySpec = new SecretKeySpec(secretKey, "AES");
byte[] encrypted = null;
try {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
encrypted = cipher.doFinal(fileData);
// Now write your logic to save encrypted data to sdcard here
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
return encrypted;
}
Decryption:
public static byte[] decodeFile(byte[] key, byte[] fileData) {
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
byte[] decrypted = null;
try {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
decrypted = cipher.doFinal(fileData);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException | BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(Exception e){
// for all other exception
e.printStackTrace();
}
return decrypted;
}
Hope above methods are useful for you!
AS with every beginner it is normal to get confused, instead of do it yourself everything learn to leverage on code reuse or written shared libraries. This will leverage on code abstraction as you are only interested in say Encryption and Decryption of JSON/Sting.
For a Full Document:
https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html
For a reusable (Java/Android) library:
https://github.com/alkathirikhalid/security
Simple Usage:
String plainText = "Your String";
String encryptionKey = "Your Encryption Key";
String IV = "Your Initial Vector";
// To Encrypt
String cipherText = AES.encrypt(plainText, encryptionKey, IV);
// To Decrypt returned value same as plainText
String originalText = AES.decrypt(cipherText, encryptionKey, IV);
Cheers.

How to get key from keystore on successful fingerprint auth

I'm creating an app where the user has two options to unlock their app, one is using a pin and the other is using a fingerprint. In order to use the fingerprint they must first set up a pin because this pin is the decryption key to get their encrypted details out of SharedPreferences.
So i've followed this tutorial here: http://www.techotopia.com/index.php/An_Android_Fingerprint_Authentication_Tutorial#Accessing_the_Android_Keystore_and_KeyGenerator
I've managed to get the app to read a fingerprint and say whether it is valid or not. But when the fingerprint is authorised I have no idea how to get that pin out of the Android keystore.
Here is some code to demonstrate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
if (!keyguardManager.isKeyguardSecure()) {
Toast.makeText(this, "Lock screen security not enabled in Settings", Toast.LENGTH_LONG).show();
return;
}
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.USE_FINGERPRINT) !=
PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Fingerprint authentication permission not enabled", Toast.LENGTH_LONG).show();
return;
}
if (!fingerprintManager.hasEnrolledFingerprints()) {
// This happens when no fingerprints are registered.
Toast.makeText(this, "Register at least one fingerprint in Settings", Toast.LENGTH_LONG).show();
return;
}
generateKey();
if (cipherInit()) {
cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(this);
helper.startAuth(fingerprintManager, cryptoObject);
}
}
protected void generateKey() {
try {
keyStore = KeyStore.getInstance("AndroidKeyStore");
} catch (Exception e) {
e.printStackTrace();
}
try {
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
} catch (NoSuchAlgorithmException |
NoSuchProviderException e) {
throw new RuntimeException("Failed to get KeyGenerator instance", e);
}
try {
keyStore.load(null);
keyGenerator.init(new
KeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build());
keyGenerator.generateKey();
} catch (NoSuchAlgorithmException |
InvalidAlgorithmParameterException
| CertificateException | IOException e) {
throw new RuntimeException(e);
}
}
public boolean cipherInit() {
try {
cipher = Cipher.getInstance(
KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
} catch (NoSuchAlgorithmException |
NoSuchPaddingException e) {
throw new RuntimeException("Failed to get Cipher", e);
}
try {
keyStore.load(null);
SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME,
null);
cipher.init(Cipher.ENCRYPT_MODE, key);
return true;
} catch (KeyPermanentlyInvalidatedException e) {
return false;
} catch (KeyStoreException | CertificateException
| UnrecoverableKeyException | IOException
| NoSuchAlgorithmException | InvalidKeyException e) {
throw new RuntimeException("Failed to init Cipher", e);
}
}
KEY_NAME is the key(pin) i'm trying to store (I think).
Then in the FingerprintHandler class there is this method:
public void onAuthenticationSucceeded(
FingerprintManager.AuthenticationResult result) {
Toast.makeText(appContext,
"Authentication succeeded.",
Toast.LENGTH_LONG).show();
}
But how do i get the key i want out of the result if at all?
So to do this I ended up encrypting the users pin in to shared preferences and then decrypting when the fingerprint auth was successful:
So to save the pin:
private static final String CHARSET_NAME = "UTF-8";
private static final String ANDROID_KEY_STORE = "AndroidKeyStore";
private static final String TRANSFORMATION = KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7;
private static final int AUTHENTICATION_DURATION_SECONDS = 30;
private KeyguardManager keyguardManager;
private static final int SAVE_CREDENTIALS_REQUEST_CODE = 1;
public void saveUserPin(String pin) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException, BadPaddingException, IllegalBlockSizeException {
// encrypt the password
try {
SecretKey secretKey = createKey();
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptionIv = cipher.getIV();
byte[] passwordBytes = pin.getBytes(CHARSET_NAME);
byte[] encryptedPasswordBytes = cipher.doFinal(passwordBytes);
String encryptedPassword = Base64.encodeToString(encryptedPasswordBytes, Base64.DEFAULT);
// store the login data in the shared preferences
// only the password is encrypted, IV used for the encryption is stored
SharedPreferences.Editor editor = BaseActivity.prefs.edit();
editor.putString("password", encryptedPassword);
editor.putString("encryptionIv", Base64.encodeToString(encryptionIv, Base64.DEFAULT));
editor.apply();
} catch (UserNotAuthenticatedException e) {
e.printStackTrace();
showAuthenticationScreen(SAVE_CREDENTIALS_REQUEST_CODE);
}
}
private SecretKey createKey() {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
keyGenerator.init(new KeyGenParameterSpec.Builder(Constants.KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setUserAuthenticationValidityDurationSeconds(AUTHENTICATION_DURATION_SECONDS)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build());
return keyGenerator.generateKey();
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
throw new RuntimeException("Failed to create a symmetric key", e);
}
}
Then to decrypt:
public String getUserPin() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, NoSuchPaddingException, UnrecoverableKeyException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
// load login data from shared preferences (
// only the password is encrypted, IV used for the encryption is loaded from shared preferences
SharedPreferences sharedPreferences = BaseActivity.prefs;
String base64EncryptedPassword = sharedPreferences.getString("password", null);
String base64EncryptionIv = sharedPreferences.getString("encryptionIv", null);
byte[] encryptionIv = Base64.decode(base64EncryptionIv, Base64.DEFAULT);
byte[] encryptedPassword = Base64.decode(base64EncryptedPassword, Base64.DEFAULT);
// decrypt the password
KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
keyStore.load(null);
SecretKey secretKey = (SecretKey) keyStore.getKey(Constants.KEY_NAME, null);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(encryptionIv));
byte[] passwordBytes = cipher.doFinal(encryptedPassword);
String string = new String(passwordBytes, CHARSET_NAME);
return string;
}
The showAuthenticationScreen method that is called looks like this:
private void showAuthenticationScreen(int requestCode) {
Intent intent = keyguardManager.createConfirmDeviceCredentialIntent(null, null);
if (intent != null) {
startActivityForResult(intent, requestCode);
}
}
And then to get the result back from showAuthenticationScreen just override onActivityResult and call saveUserPin or getUserPin again whichever is required.
The way in which the tutorial you mentioned, as well as the Fingerprint Dialog Sample provided by Google, handles authentication is by assuming that the user is authentic when onAuthenticationSucceeded() is called. The Google sample takes this a step further by checking if the Cipher provided by the can encrypt arbitrary data:
/**
* Proceed the purchase operation
*
* #param withFingerprint {#code true} if the purchase was made by using a fingerprint
* #param cryptoObject the Crypto object
*/
public void onPurchased(boolean withFingerprint,
#Nullable FingerprintManager.CryptoObject cryptoObject) {
if (withFingerprint) {
// If the user has authenticated with fingerprint, verify that using cryptography and
// then show the confirmation message.
assert cryptoObject != null;
tryEncrypt(cryptoObject.getCipher());
} else {
// Authentication happened with backup password. Just show the confirmation message.
showConfirmation(null);
}
}
/**
* Tries to encrypt some data with the generated key in {#link #createKey} which is
* only works if the user has just authenticated via fingerprint.
*/
private void tryEncrypt(Cipher cipher) {
try {
byte[] encrypted = cipher.doFinal(SECRET_MESSAGE.getBytes());
showConfirmation(encrypted);
} catch (BadPaddingException | IllegalBlockSizeException e) {
Toast.makeText(this, "Failed to encrypt the data with the generated key. "
+ "Retry the purchase", Toast.LENGTH_LONG).show();
Log.e(TAG, "Failed to encrypt the data with the generated key." + e.getMessage());
}
}
This is a valid form of authentication, but if you need to actually store and retrieve a secret (in your case a pin), it is not sufficient. Instead, you can use asymmetric cryptography to encrypt your secret, then decrypt it upon onAuthenticationSucceeded(). This is similar to how authentication is handled in the Asymmetric Fingerprint Dialog Sample, although without a back end server.

RSA Encryption Decryption Android

I have a settings screen where I want the user to fill personal details.
I want to keep them in sharedpreferences.
I would like to encrypt the data before saving in Sharedpreferences.
Only when it is used, it's in another application activity decrypt what exists in sharedpreferences and use it.
For this purpose I encrypted the information in the settings screen and save the string that was encrypted in to sharedpreferences.
In order to Decrypt I need the same privateKey and I do not know how to move it to the other activity. I tried using sharedpreferences but the program was flying.
Would appreciate help
Code:
try{
SharedPreferences.Editor editor =getActivity().getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
afterEncryptCvv = Encrypt((String) newValue,editor);
editor.putString("cvvValue", afterEncryptCvv);
editor.commit();
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
The Encrypt Function:
public static String Encrypt(String plain, SharedPreferences.Editor editor)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException
{
kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
kp = kpg.genKeyPair();
publicKey = kp.getPublic();
privateKey = kp.getPrivate();
Gson gson4 = new Gson();
String json4 = gson4.toJson(privateKey);
editor.putString("privateKey", json4);
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
encryptedBytes = cipher.doFinal(plain.getBytes());
encrypted = bytesToString(encryptedBytes);
return encrypted;
}
In The second activity:
SharedPreferences prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
try {
Gson gson4 = new Gson();
String json4 = prefs.getString("privateKey", "");
privateKey = gson4.fromJson(json4, PrivateKey.class);
cvvValue = prefs.getString(Cvv, "");
String temp = Decrypt(cvvValue);
cvvValue =temp;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
The Decrypt Function:
public String Decrypt (String result) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
BadPaddingException
{
cipher1= Cipher.getInstance("RSA");
cipher1.init(Cipher.DECRYPT_MODE, privateKey);
decryptedBytes = cipher1.doFinal(stringToBytes(result));
decrypted = new String(decryptedBytes);
return decrypted;
}
You should not store the secret key on the internal storage. Someone with a rooted device can extract it easily.
Instead, after generating the key pair, you can save it in Android Key Store (see here: http://developer.android.com/training/articles/keystore.html) and use it when needed.
For example:
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry(alias, null);

Clarification about Android public key?

I am confused by this bit of advice from http://developer.android.com/guide/google/play/billing/billing_integrate.html#billing-signatures
To keep your public key safe from malicious users and hackers, do not
embed your public key as an entire literal string. Instead, construct
the string at runtime from pieces or use bit manipulation (for
example, XOR with some other string) to hide the actual key. The key
itself is not secret information, but you do not want to make it easy
for a hacker or malicious user to replace the public key with another
key.
Does this mean that
String one = "thisIs";
String two = "MyKey";
String base64EncodedPublicKey = one + two;
PublicKey key = Security.generatePublicKey(base64EncodedPublicKey);
verified = Security.verify(key, signedData, signature);
is safer than
String base64EncodedPublicKey = "thisIsMyKey";
PublicKey key = Security.generatePublicKey(base64EncodedPublicKey);
verified = Security.verify(key, signedData, signature);
? If not, could you please give me an example in code of how to do this?
Something that involves some serious change of the key is best. Personally, I prefer using encryption, something like this would work. For the key, string together a few parts, and it should help to getting it together. Use encryptKey to get your key encrypted, then delete the real key from the source code, and you should be fairly secure. Better is to somehow get the key from a secure server, but that isn't always an option.
String encryptKey(String input)
{
byte[] inBytes=input.getBytes();
String finalString=null;
try {
Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] keyBytes=md.digest((KeyPart1+KeyPart2).getBytes());
keyBytes = Arrays.copyOf(keyBytes, 16);
SecretKey key= new SecretKeySpec(keyBytes,"AES");
IvParameterSpec ivSpec = new IvParameterSpec(new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0});
cipher.init(Cipher.ENCRYPT_MODE,key,ivSpec);
byte[] outBytes = new byte[cipher.getOutputSize(inBytes.length)];
//cipher.update(encrypted, 0, encrypted.length, decrypted, 0);
outBytes=cipher.doFinal(inBytes);
finalString=new String(Base64.encode(outBytes,0));
Log.v(TAG,"Encrypted="+finalString);
} catch (NoSuchAlgorithmException e) {
Log.e(TAG,"No Such Algorithm",e);
} catch (NoSuchPaddingException e) {
Log.e(TAG,"No Such Padding",e);
} catch (InvalidKeyException e) {
Log.e(TAG,"Invalid Key",e);
} catch (InvalidAlgorithmParameterException e) {
Log.e(TAG,"Invalid Algorithm Parameter",e);
} catch (IllegalBlockSizeException e) {
} catch (BadPaddingException e) {}
return finalString;
}
String decryptKey(String base64Text)
{
byte[] encrypted=Base64.decode(base64Text,0);
//encrypted=base64Text.getBytes();
String decryptedString=null;
try {
Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] keyBytes=md.digest((KeyPart1+KeyPart2).getBytes());
keyBytes = Arrays.copyOf(keyBytes, 16);
SecretKey key= new SecretKeySpec(keyBytes,"AES");
IvParameterSpec ivSpec = new IvParameterSpec(new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0});
cipher.init(Cipher.DECRYPT_MODE,key,ivSpec);
byte[] decrypted = new byte[cipher.getOutputSize(encrypted.length)];
//cipher.update(encrypted, 0, encrypted.length, decrypted, 0);
decrypted=cipher.doFinal(encrypted);
decryptedString=new String(decrypted);
} catch (NoSuchAlgorithmException e) {
logStackTrace(e);
} catch (NoSuchPaddingException e) {
logStackTrace(e);
} catch (InvalidKeyException e) {
logStackTrace(e);
} catch (InvalidAlgorithmParameterException e) {
logStackTrace(e);
} catch (IllegalBlockSizeException e) {
logStackTrace(e);
} catch (BadPaddingException e) {
logStackTrace(e);
}
return decryptedString;
}
Yes. Although in this case you're just concatenating strings which is not much better. The reason for this is that somebody could easily disassemble your code and access your public key. If you have to reassemble the key, it makes it much more challenging to grab the key out of the disassembled code.

Categories

Resources