android text encryption with key iv data

天大地大妈咪最大 提交于 2020-03-04 18:30:14

问题


Not data encrypt only show Null, pls change code if any mistake. i think problem is my key and iv, but i dont no how to creat it pls hellp me

 String text = Java_AES_Cipher.encrypt("123sadsad","123","vishal");
Log.i("encrypt_Text is = ", "" + text);

public static String encrypt(String key, String iv, String data) {
    try {
        if (key.length() < Java_AES_Cipher.CIPHER_KEY_LEN) {
            int numPad = Java_AES_Cipher.CIPHER_KEY_LEN - key.length();

            for(int i = 0; i < numPad; i++){
                key += "0"; //0 pad to len 16 bytes
            }

        } else if (key.length() > Java_AES_Cipher.CIPHER_KEY_LEN) {
            key = key.substring(0, CIPHER_KEY_LEN); //truncate to 16 bytes
        }


        IvParameterSpec initVector = new IvParameterSpec(iv.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

        Cipher cipher = Cipher.getInstance(Java_AES_Cipher.CIPHER_NAME);
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, initVector);

        byte[] encryptedData = cipher.doFinal((data.getBytes()));

        String base64_EncryptedData = Base64.getEncoder().encodeToString(encryptedData);
        String base64_IV = Base64.getEncoder().encodeToString(iv.getBytes("UTF-8"));

        return base64_EncryptedData + ":" + base64_IV;

    } catch (Exception ex) {
        ex.printStackTrace();
    }

    return null;
}

Not data encrypt only show Null, pls change code if any mistake.


回答1:


import android.util.Base64;

import javax.crypto.Cipher;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import javax.crypto.spec.SecretKeySpec;
import java.util.Arrays;

import javax.crypto.spec.IvParameterSpec;

public class Decrypter {

    public static byte[] generateKey() throws GeneralSecurityException, UnsupportedEncodingException {
        final String KEY = "com.taba.notes";
        byte[] binary = KEY.getBytes("UTF-8");
        MessageDigest sha = MessageDigest.getInstance("SHA-1");
        binary = sha.digest(binary);
        // Use only first 128 bit.
        binary = Arrays.copyOf(binary, 16);
        return binary;
    }

    public static String encrypt(byte[] key, String value) throws GeneralSecurityException {
        // Argument validation.
        if (key.length != 16) {
            throw new IllegalArgumentException("Invalid key size.");
        }

        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));

        byte[] original = value.getBytes(Charset.forName("UTF-8"));
        byte[] binary = cipher.doFinal(original);
        return Base64.encodeToString(binary, Base64.DEFAULT);
    }

    public static String decrypt(byte[] key, String encrypted) throws GeneralSecurityException {
        // Argument validation.
        if (key.length != 16) {
            throw new IllegalArgumentException("Invalid key size.");
        }

        // Setup AES tool.
        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));

        byte[] binary = Base64.decode(encrypted, Base64.DEFAULT);
        byte[] original = cipher.doFinal(binary);
        return new String(original, Charset.forName("UTF-8"));
    }
}

Example:

try{
    byte[] key = Decrypter.generateKey();
    String title = Decrypter.decrypt( key, note.getTitle() );
    deleteFolder( title, position );
} catch(Exception e) {
    e.printStackTrace();
}



回答2:


Your method returns null because it throws an exception on the cipher.init method. In ENCRYPT_MODE you're not supposed to supply an initialization vector. The initialization vector is needed in order to DECRYPT the data and not encrypt it.

Try this instead:

public static Key getKey(String keyAlias) {
   KeyStore keystore = KeyStore.getInstance("AndroidKeyStore");
   keystore.load(null);
   if(keystore.containsAlias(keyAlias)){
      return keyStore.getKey(keyAlias, null);
   }
    KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
    KeyGenParameterSpec.Builder builder =
        KeyGenParameterSpec.Builder(keyAlias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_CBC) 
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7); 
    KeyGenParameterSpec keyGenParameterSpec = builder.build();
    keyGenerator.init(keyGenParameterSpec);
    //this creates the key and stores it in AndroidKeyStore for later use
    return keyGenerator.generateKey();
}
public static String encrypt(String keyAlias, String data) {
try {

    SecretKey key = getKey(keyAlias);
    Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES+"/"+KeyProperties.BLOCK_MODE_CBC+"/"+KeyProperties.ENCRYPTION_PADDING_PKCS7);


    cipher.init(Cipher.ENCRYPT_MODE, key);
    //you need to store the iv (maybe in shared preferences)
    //in order to be able to decrypt the data
    //The IV is auto generated by the cipher, you don't need to create it
    //for every encrypt operation the IV is different
    IvParameterSpec initVector = cipher.getIv();

    byte[] encryptedData = cipher.doFinal((data.getBytes()));

    String base64_EncryptedData = Base64.getEncoder().encodeToString(encryptedData);
    //do not add the IV to the encrypted data, store it along side the data instead
    return base64_EncryptedData;

} catch (Exception ex) {
    ex.printStackTrace();
}

return null;

}

  public static byte[] decrypt(String keyAlias, String base64EncryptedData, byte[] iv) {
          SecretKey key = getKey(keyAlias);
          Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES+"/"+KeyProperties.BLOCK_MODE_CBC+"/"+KeyProperties.ENCRYPTION_PADDING_PKCS7);
          //here you actually need the IV
          cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
          byte[] dataToDecrypt = Base64.Decoder().decodeString(base64EncryptedData);
          byte[] decryptedData = cipher.doFinal(dataToDecrypt);
          return decryptedData;
}

PS. very nice idea to post this question as a comment to one of my previous answers :)



来源:https://stackoverflow.com/questions/59092141/android-text-encryption-with-key-iv-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!