Android 字符串加密/解密

我想String从EditTextusing加密和解密 a AndroidKeyStore。我的问题是在解密过程中得到一个BadPaddingException.


密钥生成器代码:


        KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");


        KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(ALIAS, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT).

                setBlockModes(KeyProperties.BLOCK_MODE_GCM).setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE).build();


        keyGenerator.init(keyGenParameterSpec);

        keyGenerator.generateKey();

加密代码:


            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");

            keyStore.load(null);


            KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore.getEntry(ALIAS, null);

            SecretKey secretKey = secretKeyEntry.getSecretKey();


            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

            cipher.init(Cipher.ENCRYPT_MODE, secretKey);


            cipherIV = cipher.getIV();


            plainText.setText(new String(cipher.doFinal(plainText.getText().toString().getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));

解密代码:


            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");

            keyStore.load(null);


            final KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore.getEntry(ALIAS, null);

            final SecretKey secretKey = secretKeyEntry.getSecretKey();


            final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

            final GCMParameterSpec spec = new GCMParameterSpec(128, cipherIV);

            cipher.init(Cipher.DECRYPT_MODE, secretKey, spec);


            byte[] decrypted = cipher.doFinal(plainText.getText().toString().getBytes(StandardCharsets.UTF_8));

            plainText.setText(new String(decrypted, StandardCharsets.UTF_8));


UYOU
浏览 139回答 2
2回答

肥皂起泡泡

这一行是错误的:plainText.setText(new String(cipher.doFinal(plainText.getText().toString().getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));如果我们把它分开,我们有类似的东西byte [] cipherBytes = cipher.doFinal(plainText.getText().toString().getBytes(StandardCharsets.UTF_8)); plainText.setText(new String(cipherBytes, StandardCharsets.UTF_8);问题是这cipherBytes是一个任意字节序列而不是字符串的字符。String 构造函数会悄悄地用其他东西替换无效字符,这是一个破坏数据的过程。如果要显示密码字节或以其他方式将其发送到面向字符的通道,则必须对其进行编码。通常编码是 base64 或十六进制。要解密字符串,您必须先将其解码为字节,然后再解密。例子:byte [] cipherBytes = cipher.doFinal(plainText.getText().toString().getBytes(StandardCharsets.UTF_8)); plainText.setText(Base64.encodeToString(cipherBytes, Base64.DEFAULT));并解密:byte[] cipherBytes = Base64.decode(plainText.getText().toString(), Base64.DEFAULT); byte[] decrypted = cipher.doFinal(cipherBytes);

牧羊人nacy

byte[] decrypted = cipher.doFinal(plainText.getText().toString().getBytes(StandardCharsets.UTF_8));由于 的调用,此行可能无法正常工作getBytes(StandardCharsets.UTF_8)。如果您EditText是十六进制表示,请尝试将其转换为字符串,然后调用getBytes(). 例如public static byte[] convertHexStringToByteArray(String hexString) {&nbsp; &nbsp; int l = hexString.length();&nbsp; &nbsp; byte[] data = new byte[l/2];&nbsp; &nbsp; for (int i = 0; i < l; i += 2) {&nbsp; &nbsp; &nbsp; &nbsp; data[i/2] = (byte)((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i+1), 16));&nbsp; &nbsp; }&nbsp; &nbsp; return data;}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java