1

私は3つのクラスを持っています:

  1. AESCrypt
  2. ChooseMasterPasswordActivity
  3. UnlockPocketアクティビティ

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 に答える