Android和node.js AES使用SALT + PASSWORD + VECTOR(IV)进行加密解密

时间:2016-07-13 06:55:21

标签: android encryption aes

如何使用带有Salt +密码+ iv的AES加密和解密android中的字符串。我希望代码等同于https://stackoverflow.com/a/27893935/5582162。这个链接有node.js和iOS的工作代码,但我想要android格式的相同/等效代码。

使用上述链接 -
例如
RawData: pravin
密码: sbifast12
盐: gettingsaltyfoo!
iv: QmBSbUZMUwld31DPrqyVSA ==
加密密钥应为: AbvDUXUG9p1ysz1a1ZANSA ==

我尝试过的代码:

try {
            // byte[] salt = generateSalt();
            byte[] salt = saltStr.getBytes();
           // Log.i(TAG, "Salt: " + salt.length + " " + HexEncoder.toHex(salt));
            PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt, PBE_ITERATION_COUNT, 128);
            SecretKeyFactory factory = SecretKeyFactory.getInstance(PBE_ALGORITHM);
            SecretKey tmp = factory.generateSecret(pbeKeySpec);
            SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
            byte[] key = secret.getEncoded();
            //Log.i(TAG, "Key: " + HexEncoder.toHex(key));

            // PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, ITERATION_COUNT);

            Cipher encryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM);

            // byte[] encryptionSalt = generateSalt();
            // Log.i(TAG, "Encrypted Salt: " + encryptionSalt.length + " " + HexEncoder.toHex(encryptionSalt));
            // PBEParameterSpec pbeParamSpec = new PBEParameterSpec(encryptionSalt, 1000);
            // byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
            Log.i(TAG, encryptionCipher.getParameters() + " ");
          // byte[] iv = generateIv();
           //byte[] iv ="QmBSbUZMUwld31DPrqyVSA==".getBytes();
            IvParameterSpec ivspec = new IvParameterSpec(Arrays.copyOf(iv,16));

            encryptionCipher.init(Cipher.ENCRYPT_MODE, secret, ivspec);
            byte[] encryptedText = encryptionCipher.doFinal(plainText.getBytes());
           // Log.i(TAG, "Encrypted: " + new String(encryptedText));
            Log.i(TAG, "Encrypted: " + Base64.encodeToString(encryptedText, Base64.DEFAULT));

            Cipher decryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM);
            decryptionCipher.init(Cipher.DECRYPT_MODE, secret, ivspec);
            byte[] decryptedText = decryptionCipher.doFinal(encryptedText);
            Log.i(TAG, "Decrypted....: " + new String(decryptedText));

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

还有......

public class AesEncryption2 {


    private static String password = "sbifast12";

    /**
     * vector array for encryption & decryption
     */
    private static byte[] iv = "QmBSbUZMUwld31DPrqyVSA==".getBytes();
    private static String IV = "QmBSbUZMUwld31DPrqyVSA==";
    private static String salt = "gettingsaltyfoo!";
    private static String CIPHERTEXT = "CIPHERTEXT!";


    public static  void main(String rawData) {

        byte[] interop_iv = Base64.decode(IV, Base64.DEFAULT);
       // byte[] iv = null;
        byte[] ciphertext;
        SecretKeySpec secret=null;
        try {
            secret = generateKey(password.toCharArray(), salt.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
        Map result = null;
        try {
            result = encrypt(rawData, iv, secret);
        } catch (Exception e) {
            e.printStackTrace();
        }


        ciphertext = (byte[]) result.get(CIPHERTEXT);
        iv = (byte[]) result.get(IV);
        System.out.println("Cipher text:" + Base64.encode(ciphertext, Base64.DEFAULT));
        System.out.println("IV:" + Base64.encode(iv, Base64.DEFAULT) + " (" + iv.length + "bytes)");
        System.out.println("Key:" + Base64.encode(secret.getEncoded(), Base64.DEFAULT));
        try {
            System.out.println("Deciphered: " + decrypt(ciphertext, iv, secret));
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Interop demonstration. Using a fixed IV that is used in the C#
        // example
        try {
            result = encrypt(rawData, interop_iv, secret);
        } catch (Exception e) {
            e.printStackTrace();
        }
        ciphertext = (byte[]) result.get(CIPHERTEXT);
        iv = (byte[]) result.get(IV);

        String text = Base64.encodeToString(ciphertext, Base64.DEFAULT);

        System.out.println();
        System.out.println("--------------------------------");
        System.out.println("Interop test - using a static IV");
        System.out.println("The data below should be used to retrieve the secret message by the receiver");
        System.out.println("Cipher text:  " + text);
        System.out.println("IV:           " + Base64.encodeToString(iv, Base64.DEFAULT));
        try {
            decrypt(Base64.decode(text, Base64.DEFAULT), iv, secret);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static SecretKeySpec generateKey(char[] password, byte[] salt) throws Exception {
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec spec = new PBEKeySpec(password, salt, 1024, 128);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKeySpec secret = new SecretKeySpec(tmp.getEncoded(), "AES");
        return secret;
    }

    public static Map encrypt(String cleartext, byte[] iv, SecretKeySpec secret) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        // If the IvParameterSpec argument is omitted (null), a new IV will be
        // created
        cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(iv));
        AlgorithmParameters params = cipher.getParameters();
        byte[] usediv = params.getParameterSpec(IvParameterSpec.class).getIV();
        byte[] ciphertext = cipher.doFinal(cleartext.getBytes("UTF-8"));
        Map result = new HashMap();
        result.put(IV, usediv);
        result.put(CIPHERTEXT, ciphertext);
        return result;
    }


    public static String decrypt(byte[] ciphertext, byte[] iv, SecretKeySpec secret) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
        String plaintext = new String(cipher.doFinal(ciphertext), "UTF-8");
        return plaintext;
    }

第三种方法:

 private static final String ALGO = "AES";

    /**
     * key value for encryption & decryption
     */
    private static String password = "sbifast12";
    private static byte[] iv = "QmBSbUZMUwld31DPrqyVSA==".getBytes();
    private static String IV = "QmBSbUZMUwld31DPrqyVSA==";
    private static String salt = "gettingsaltyfoo!";

    /**
     * constructor with two variable parameters
     * @param password
     * @param iv
     */
  /*  public AESEncryption(String password, String iv) {
        if (password == null || iv == null)
            throw new NullPointerException("Encryption values can not be null!");

        this.password = password.getBytes();
        this.iv = iv.getBytes();
    }*/

    /**
     * encrypt given string data
     *
     * @param rawdata
     * @return
     * @throws Exception
     */
    public static String encrypt(String rawdata) throws Exception {
        if (rawdata == null)
            throw new NullPointerException("Raw data can not be null!");
        //SecretKeySpec sKey = (SecretKeySpec) generateKeyFromPassword(password, saltBytes);
        //SecretKey key = new SecretKeySpec(Base64.decode(salt,Base64.DEFAULT), "AES");
        // Key key = generateKey();
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
       /* cipher.init(Cipher.ENCRYPT_MODE, generateKeyFromPassword("sbifast12", salt.getBytes()),
                new IvParameterSpec(Arrays.copyOf(IV.getBytes("UTF-8"), 16)));
        */
        cipher.init(Cipher.ENCRYPT_MODE, generateKeyFromPassword("sbifast12", salt.getBytes()),
                new IvParameterSpec(Arrays.copyOf(IV.getBytes(),16)));
        byte[] encVal = cipher.doFinal(rawdata.getBytes());
        String encryptedValue = Base64.encodeToString(encVal, Base64.DEFAULT);

        System.out.println("%%%%%%% Encrypted Text: " + encryptedValue);
        return encryptedValue;
    }

    public static SecretKey generateKeyFromPassword(String password, byte[] saltBytes) throws GeneralSecurityException {

        KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, 1000, 128);
      SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
      //  SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithSHA256AND256BITAES");
        SecretKey secretKey = keyFactory.generateSecret(keySpec);

        return new SecretKeySpec(secretKey.getEncoded(), "AES");
    }

    /**
     * decrypt given string data
     *
     * @param encryptedData
     * @return
     * @throws Exception
     */
    public String decrypt(String encryptedData) throws Exception {
        if (encryptedData == null)
            throw new NullPointerException("Encrypted data can not be null!");

        Key key = generateKey();
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
        byte[] decodedValue = Base64.decode(encryptedData, Base64.DEFAULT);
        byte[] decValue = cipher.doFinal(decodedValue);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    }

    /**
     * key generator
     *
     * @return
     * @throws Exception
     */
    private Key generateKey() throws Exception {
        Key key = new SecretKeySpec("sbifast12".getBytes(), ALGO);
        return key;
    }

1 个答案:

答案 0 :(得分:0)

public class Cryptography {

    private static final String TAG = "Cryptography";


    //secretKey64 is genereated from salt and password..!!! (taken directly from server side)

    private static String secretKey64 = "*****1hrHpnONd8ZJ*****c756ikDmZU1v*****8Xjg=";
    private static String secretKeyAlgorithm = "AES";
    private static String cipherAlgorithm = "AES/CBC/PKCS7Padding";
    private static String iv64 = "QmBSbU*****d31DPr*****==";
    private static String charsetName = "UTF-8";
    //  private static int base64Mode = android.util.Base64.DEFAULT;
    private static int base64Mode = android.util.Base64.NO_WRAP;

    public static String encrypt(String plainText) throws NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, InvalidAlgorithmParameterException, UnsupportedEncodingException
            , IllegalBlockSizeException, BadPaddingException {
        String encrytedText = "";
        if (plainText == null) {
            return null;
        } else {
            SecretKey secretKey = new SecretKeySpec(android.util.Base64.decode(secretKey64, 0), secretKeyAlgorithm);
            IvParameterSpec iv = new IvParameterSpec(android.util.Base64.decode(iv64, 0));
            Cipher cipher = Cipher.getInstance(cipherAlgorithm);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);

            byte[] dataBytes = plainText.getBytes(charsetName);
            encrytedText = Base64.encodeToString(cipher.doFinal(dataBytes), base64Mode);
        }
        // Log.d(TAG, "ENCRYPT >>>> : " + encrytedText);

        return encrytedText;
    }


    public static String decrypt(String encryptedText) throws NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, InvalidAlgorithmParameterException, UnsupportedEncodingException
            , IllegalBlockSizeException, BadPaddingException, NullPointerException {
        String plainText = "";

        SecretKey secretKey = new SecretKeySpec(android.util.Base64.decode(secretKey64, 0), secretKeyAlgorithm);
        IvParameterSpec iv = new IvParameterSpec(android.util.Base64.decode(iv64, 0));
        byte[] dataBytesD = Base64.decode(encryptedText, base64Mode);
        Cipher cipherD = Cipher.getInstance(cipherAlgorithm);
        cipherD.init(2, secretKey, iv);
        //Log.d(TAG, "DECRYPT text:- >>>> : " + encryptedText);
        byte[] dataBytesDecrypted = cipherD.doFinal(dataBytesD);
        try {
            plainText = new String(dataBytesDecrypted);
        } catch (NullPointerException e) {
            e.printStackTrace();
        }

        //Log.d(TAG, "DECRYPT >>>> : " + plainText);
        return plainText;
    }
}