android - Android+crypto:导出公钥,使用openssl加密,然后回读
问题描述
这就是我想要做的:
- 在 Android 手机上生成 RSA 密钥
- 将公钥导出到 linux 机器
- 使用 OpenSSL 和该公钥加密消息
- 在Android手机上获取消息,解密并阅读。
我想我在 Android 上处理了密钥生成:
fun createKeys() {
val kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore")
val ks = KeyStore.getInstance("AndroidKeyStore").apply {
load(null)
}
val parameterSpec = KeyGenParameterSpec.Builder(
"my_alias",
KeyProperties.PURPOSE_DECRYPT or KeyProperties.PURPOSE_ENCRYPT
).run {
setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
setKeySize(2048)
setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
setCertificateSubject(X500Principal("CN=My_CN, O=My_O"))
build()
}
kpg.initialize(parameterSpec)
kpg.generateKeyPair()
}
fun exportPubKey() {
val privateKeyEntry = keyStore.getEntry("my_alias", null) as KeyStore.PrivateKeyEntry
val publicKey = privateKeyEntry.certificate.publicKey
val encoded = String(Base64.encode(publicKey.encoded, Base64.DEFAULT))
// write to file key.pub
}
fun decrypt() {
// read from file file.enc
val privateKeyEntry =
keyStore.getEntry("my_alias", null) as
KeyStore.PrivateKeyEntry
val privateKey = privateKeyEntry.privateKey
val cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding",
"AndroidKeyStoreBCWorkaround")
cipher.init(Cipher.DECRYPT_MODE, privateKey)
val message = cipher.doFinal(Base64.decode(file.toString(),
Base64.DEFAULT))
}
Note: within the app, I'm able to encrypt into a file and decrypt with the code above
在 linux 盒子上:
$ openssl rsautl -encrypt -pkcs -pubin -inkey key.pub -in file.txt -out temp.enc
$ openssl -e -base64 -in temp.enc -out file.enc
I then push the file to the Android phone, run the app, but I'm getting:
FATAL EXCEPTION: main
Process: com.test.key, PID: 28034
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.key/com.test.key.MainActivity}: javax.crypto.IllegalBlockSizeException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: javax.crypto.IllegalBlockSizeException
at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:519)
at javax.crypto.Cipher.doFinal(Cipher.java:2055)
at com.test.key.MainActivity.decrypt(MainActivity.kt:190)
at com.test.key.MainActivity.onCreate(MainActivity.kt:92)
at android.app.Activity.performCreate(Activity.java:7825)
at android.app.Activity.performCreate(Activity.java:7814)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1306)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: android.security.KeyStoreException: Unknown error
at android.security.KeyStore.getKeyStoreException(KeyStore.java:1303)
at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:224)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:506)
at javax.crypto.Cipher.doFinal(Cipher.java:2055)
at com.test.key.MainActivity.decrypt(MainActivity.kt:190)
at com.test.key.MainActivity.onCreate(MainActivity.kt:92)
at android.app.Activity.performCreate(Activity.java:7825)
at android.app.Activity.performCreate(Activity.java:7814)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1306)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
解决方案
问题是每次启动应用程序时,我基本上都是在创建一对新的密钥。因此,以前使用公钥加密的任何文件都无法解密。即使在 POC 上工作,使用 OOP 也很重要,因此代码不会被埋没。
推荐阅读
- google-apps-script - 使用谷歌脚本将谷歌驱动器视频插入谷歌幻灯片
- javascript - axios拦截器拦截所有axios请求
- asp.net - 如何在 Identity Server 4 保护的 webapi 中访问自定义声明?
- java - 没有虚拟方法 verifyPhoneNumber,致命异常:main
- mql4 - 为什么这个字符串函数不更新?MQL4
- java - Java 中的刽子手游戏并没有脱离循环
- python - 如何修复在赋值前引用的第 6 行封闭范围中定义的“局部变量”prev_time”错误
- html - Sendgrid 暗模式与两个徽标的兼容性
- python - 从python3中的div中获取特定文本
- javascript - 将字符串中的空格替换为值“N/A”-Javascript