1

我有 3 节课:

  1. AESCrypt
  2. 选择MasterPasswordActivity
  3. 解锁PocketActivity

我成功地将数据添加到 SQLite 数据库,但我在解密数据库中的数据时遇到问题。

我收到此错误:

 W/System.err(1034): javax.crypto.BadPaddingException: pad block corrupted.

在 ChooseMasterPasswordActivity 类中,我使用此代码将加密文本添加到 SQLite 数据库。

String masterKey, encryptedMPW;
        masterKey = tvPassword.getText().toString();

        AESCrypt aes = new AESCrypt();
        encryptedMPW =  aes.encrypt(masterKey);

        user = new User(null, encryptedMPW);
        userDao.insert(user);

在类 UnlockPocketActivity 我有方法 createMasterPassword() 与此代码:

private void checkMasterPassword() throws Exception {

    String pw = tvUnlockMPW.getText().toString();
    String decryptedMPW;

    AESCrypt aes = new AESCrypt();

    decryptedMPW = aes.decrypt(map.get("MPW").toString());



    if (pw.equals(decryptedMPW)) {
        Intent i = new Intent(UnlockPocketActivity.this,
                MainListActivity.class);
        startActivity(i);
    } else {
        Toast.makeText(getApplicationContext(), "Pogresna sifra...",
                Toast.LENGTH_SHORT).show();
    }
}

我将此代码用于 AESCrypt 类:

公共类 AESCrypt {

private final Cipher cipher;
private final SecretKeySpec key;
private AlgorithmParameterSpec spec;
private String encryptedText, decryptedText;
private String password = "PASSWORD";

public AESCrypt() throws Exception {

    // hash password with SHA-256 and crop the output to 128-bit for key
    MessageDigest digest = MessageDigest.getInstance("SHA-256");
    digest.update(password.getBytes("UTF-8"));
    byte[] keyBytes = new byte[16];
    System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);

    cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    key = new SecretKeySpec(keyBytes, "AES");
    spec = getIV();
    }

public AlgorithmParameterSpec getIV() {
    AlgorithmParameterSpec ivspec;
    byte[] iv = new byte[cipher.getBlockSize()];
    new SecureRandom().nextBytes(iv);
    ivspec = new IvParameterSpec(iv);
    return ivspec;
    }

public String encrypt(String plainText) throws Exception {      
    cipher.init(Cipher.ENCRYPT_MODE, key, spec);
    byte[] encrypted = cipher.doFinal(plainText.getBytes());
    encryptedText = Base64.encodeToString(encrypted, Base64.DEFAULT);
    return encryptedText;
}

public String decrypt(String cryptedText) throws Exception {
    cipher.init(Cipher.DECRYPT_MODE, key, spec);
    byte[] bytes = Base64.decode(cryptedText, Base64.DEFAULT);
    byte[] decrypted = cipher.doFinal(bytes);
    decryptedText = new String(decrypted, "UTF-8");
    return decryptedText;
}   

}

4

1 回答 1

2

您似乎初始化了初始化向量SecureRandom(),每次调用都会产生不同的数据。

byte[] iv = new byte[cipher.getBlockSize()];
new SecureRandom().nextBytes(iv);
ivspec = new IvParameterSpec(iv);

初始化向量在加密和解密时需要相同。将初始化向量与加密数据一起保存,或者找到一种生成它的方法,以便在加密和解密时得到相同的结果。它不需要是秘密的,但它应该随着你加密的每一个新事物而不同。

于 2013-03-28T18:26:50.167 回答