通过指纹认证activity和处理程序后如何使用加密对象(密钥)加密android中的内容?
how to use the crypto object (key) after passing the fingerprint authentication activity and handler to encrypt something in android?
我有下面的源代码来生成密钥并在通过指纹认证后初始化 Chiper 用于加密(使用一些全局变量)
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);
}
}
在指纹activity
中的指纹认证码后调用函数是这样的
generateKey();
if (cipherInit()) {
FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(this);
helper.startAuth(fingerprintManager, cryptoObject);
}
这是 FingerprintHandler 代码
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);
}
在将 activity 定向到 HomeActivity 的身份验证成功之后,我想使用已经生成的密钥和 HomeActivity 中早些时候已经初始化的 Chiper 加密一些东西,但我不知道如何调用密钥和 Chiper之前已经生成过,有什么例子指纹认证后如何加密?这是我在大学的期末项目,所以我非常感谢任何能回答这个问题的人
一旦您在密钥库中生成了密钥,就非常简单了。你只需要使用相同的初始化向量(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);
编辑:
我不确定您能否通过活动传递 Cipher,但您肯定可以从任何 activity 检索 KeyStore 中的密钥。您只需要用于生成密钥的密钥名称:
SecretKey cipherKey = (SecretKey) keyStore.getKey("keyName", null);
然后需要重新初始化Cipher
重要提示:每次加密一个数据都需要初始化Cipher,否则会抛出异常提示不能使用两次相同的初始化用于加密的向量 (IV)。
我有下面的源代码来生成密钥并在通过指纹认证后初始化 Chiper 用于加密(使用一些全局变量)
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);
}
}
在指纹activity
中的指纹认证码后调用函数是这样的generateKey();
if (cipherInit()) {
FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(this);
helper.startAuth(fingerprintManager, cryptoObject);
}
这是 FingerprintHandler 代码
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);
}
在将 activity 定向到 HomeActivity 的身份验证成功之后,我想使用已经生成的密钥和 HomeActivity 中早些时候已经初始化的 Chiper 加密一些东西,但我不知道如何调用密钥和 Chiper之前已经生成过,有什么例子指纹认证后如何加密?这是我在大学的期末项目,所以我非常感谢任何能回答这个问题的人
一旦您在密钥库中生成了密钥,就非常简单了。你只需要使用相同的初始化向量(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);
编辑:
我不确定您能否通过活动传递 Cipher,但您肯定可以从任何 activity 检索 KeyStore 中的密钥。您只需要用于生成密钥的密钥名称:
SecretKey cipherKey = (SecretKey) keyStore.getKey("keyName", null);
然后需要重新初始化Cipher
重要提示:每次加密一个数据都需要初始化Cipher,否则会抛出异常提示不能使用两次相同的初始化用于加密的向量 (IV)。