Don*_*rty 6 encryption android rsa keystore android-keystore
我正在尝试使用Android 4.3中引入的Android密钥库提供程序生成和存储的私钥对Android上的字符串进行编码和解码
我可以使用以下代码成功生成并获取私钥:
private void generatePrivateKey(Activity context, String alias){
/** Generate a new entry in the KeyStore by using the * KeyPairGenerator API. We have to specify the attributes for a * self-signed X.509 certificate here so the KeyStore can attach * the public key part to it. It can be replaced later with a * certificate signed by a Certificate Authority (CA) if needed. */
Calendar cal = Calendar.getInstance();
Date now = cal.getTime();
cal.add(Calendar.YEAR, 1);
Date end = cal.getTime();
KeyPairGenerator kpg = null;
try {
kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
}
try {
kpg.initialize(new KeyPairGeneratorSpec.Builder(context)
.setAlias(alias)
.setStartDate(now)
.setEndDate(end)
.setSerialNumber(BigInteger.valueOf(1))
.setSubject(new X500Principal("CN=" + alias))
.build());
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
KeyPair kp = kpg.generateKeyPair();
/*
* Load the Android KeyStore instance using the the
* "AndroidKeyStore" provider to list out what entries are
* currently stored.
*/
KeyStore ks = null;
try {
ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
Enumeration<String> aliases = ks.aliases();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
/*
* Use a PrivateKey in the KeyStore to create a signature over
* some data.
*/
KeyStore.Entry entry = null;
try {
entry = ks.getEntry(alias, null);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnrecoverableEntryException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
if (!(entry instanceof KeyStore.PrivateKeyEntry)) {
Log.w("E", "Not an instance of a PrivateKeyEntry");
}
else{
Log.w("E", "Got Key!");
privateKeyEntry = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
}
}
Run Code Online (Sandbox Code Playgroud)
这是我用于加密(编码)和解密(解码)的代码:
private String encryptString(String value){
byte[] encodedBytes = null;
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
cipher.init(Cipher.ENCRYPT_MODE, privateKeyEntry );
encodedBytes = cipher.doFinal(value.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return Base64.encodeToString(encodedBytes, Base64.DEFAULT);
}
private String decryptString(String value){
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
c.init(Cipher.DECRYPT_MODE, privateKeyEntry );
decodedBytes = c.doFinal(Base64.decode(value, Base64.DEFAULT));
} catch (Exception e) {
e.printStackTrace();
}
return new String(decodedBytes);
}
Run Code Online (Sandbox Code Playgroud)
加密似乎工作正常,但当我尝试解密它时,我收到以下错误:
javax.crypto.BadPaddingException: error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02
Run Code Online (Sandbox Code Playgroud)
谷歌搜索似乎表明用于解密的私钥与用于解密的私钥不同,但在我的代码中,我使用完全相同的私钥.我也看到它建议手动设置密钥大小,但在KeyPairGenerator构建器中执行此操作,如下所示:
.setKeySize(1024);
Run Code Online (Sandbox Code Playgroud)
没有工作,似乎只在API 19上可用,我需要针对API 18.
任何人都可以帮助我指出解决方案的正确方向吗?
您没有使用公钥进行加密。
当您使用非对称加密算法时,您需要使用公钥来加密您的数据,而私钥仅用于再次解密。
除了加密之外,您还可以使用私钥进行签名,但这不是您想要的,所以我们暂时忘记这一点。
如果您在加密字符串时从生成的对中获取公钥,并在解密时获取私钥,您应该会得到所需的结果。您可以通过访问保存私钥的密钥库对象中的证书来提取公钥。
或者,您也可以使用AES 等对称算法,这样您的工作就会变得更加轻松。另外,对称算法通常要快得多,这就是为什么非对称算法从不纯粹使用,而是与对称算法结合使用,构建所谓的混合算法。
| 归档时间: |
|
| 查看次数: |
5472 次 |
| 最近记录: |