代码之家  ›  专栏  ›  技术社区  ›  Aswin Darma Saputra

在通过指纹认证活动和处理程序后,如何使用加密对象(密钥)在android中加密?

  •  0
  • Aswin Darma Saputra  · 技术社区  · 7 年前

    private KeyStore keyStore;
    // Variable used for storing the key in the Android Keystore container
    private static final String KEY_NAME = "androidHive";
    private Cipher cipher;
    private TextView textView;
    
    @TargetApi(Build.VERSION_CODES.M)
    protected void generateKey() {
        try {
            keyStore = KeyStore.getInstance("AndroidKeyStore");
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        KeyGenerator keyGenerator;
        try {
            keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
            throw new RuntimeException("Failed to get KeyGenerator instance", e);
        }
    
        try {
            keyStore.load(null);
            keyGenerator.init(new
                    KeyGenParameterSpec.Builder(KEY_NAME,
                    KeyProperties.PURPOSE_ENCRYPT |
                            KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                    .setUserAuthenticationRequired(true)
                    .setEncryptionPaddings(
                            KeyProperties.ENCRYPTION_PADDING_PKCS7)
                    .build());
            keyGenerator.generateKey();
        } catch (NoSuchAlgorithmException |
                InvalidAlgorithmParameterException
                | CertificateException | IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    @TargetApi(Build.VERSION_CODES.M)
    public boolean cipherInit() {
        try {
            cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new RuntimeException("Failed to get Cipher", e);
        }
    
        try {
            keyStore.load(null);
            SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME,
                    null);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            return true;
        } catch (KeyPermanentlyInvalidatedException e) {
            return false;
        } catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException | NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException("Failed to init Cipher", e);
        }
    }
    

    在指纹活动中的指纹验证码之后,该函数被这样调用

    generateKey();
    
    if (cipherInit()) {
        FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(cipher);
        FingerprintHandler helper = new FingerprintHandler(this);
        helper.startAuth(fingerprintManager, cryptoObject);
    }
    

    private Context context;
    
    // Constructor
    public FingerprintHandler(Context mContext) {
        context = mContext;
    }
    
    public void startAuth(FingerprintManager manager, FingerprintManager.CryptoObject cryptoObject) {
        CancellationSignal cancellationSignal = new CancellationSignal();
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        manager.authenticate(cryptoObject, cancellationSignal, 0, this, null);
    }
    
    @Override
    public void onAuthenticationError(int errMsgId, CharSequence errString) {
        this.update("Fingerprint Authentication error\n" + errString);
    }
    
    @Override
    public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
        this.update("Fingerprint Authentication help\n" + helpString);
    }
    
    @Override
    public void onAuthenticationFailed() {
        this.update("Fingerprint Authentication failed.");
    }
    
    @Override
    public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
        ((Activity) context).finish();
        Intent intent = new Intent(context, HomeActivity.class);
        context.startActivity(intent);
    }
    
    private void update(String e){
        TextView textView = (TextView) ((Activity)context).findViewById(R.id.errorText);
        textView.setText(e);
    }
    

    在认证成功将活动定向到HomeActivity之后,我想用HomeActivity中已经生成的密钥和之前已经初始化的Chipper加密一些东西,但我不知道如何调用之前已经生成的密钥和Chipper,举个例子,在指纹认证之后如何进行加密?这是我在大学的最后一个项目,所以我非常感谢任何能回答这个问题的人

    1 回复  |  直到 7 年前
        1
  •  0
  •   Omar Aflak    7 年前

    一旦在密钥库中生成了密钥,就相当容易了。您只需要使用相同的初始化向量(IV)来加密和解密。

    // encryption
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] ivBytes = cipher.getIV();
    String dataToEncrypt = "Super secret data";
    byte[] data = dataToEncrypt.getBytes();
    byte[] encryptedData = cipher.doFinal(data);
    
    // decryption
    cipher.init(Cipher.DECRYPT_MODE, key, ivBytes);
    byte[] decryptedData = cipher.doFinal(encryptedData);
    String originalData = new String(decryptedData);
    

    编辑:

    我不确定您是否可以通过活动传递密码,但可以肯定地从任何活动中检索密钥库中的密钥。您只需要用于生成密钥的密钥名:

    SecretKey cipherKey = (SecretKey) keyStore.getKey("keyName", null);
    

    重要提示: