【问题标题】:Android + crypto: export public key, use openssl to encrypt, then read backAndroid+crypto:导出公钥,使用openssl加密,然后回读
【发布时间】:2020-10-14 01:24:15
【问题描述】:

这就是我想要做的:

  • 在 Android 手机上生成 RSA 密钥
  • 将公钥导出到 linux 机器
  • 使用 OpenSSL 和该公钥加密消息
  • 在安卓手机上获取消息,解密并阅读。

我认为我在 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) 

【问题讨论】:

  • 它适用于我使用 Android 模拟器。但是,如果我改为将空的 base64 字符串 "" 提供给解密过程,我会得到与您相同的错误。我注意到您的第二个 openssl 命令不正确。也许您的测试流程没有识别这一点并生成一个空的密码文件。
  • 通常,问题出在屏幕和椅子之间。每当启动应用程序时都会调用生成新密钥的代码。

标签: android encryption openssl rsa


【解决方案1】:

问题在于,每次启动应用程序时,我基本上都是在创建一对新密钥。因此,以前使用公钥加密的任何文件都无法解密。 即使在 POC 上工作,使用 OOP 也很重要,这样代码就不会被埋没。

【讨论】:

    猜你喜欢
    • 2019-02-23
    • 2020-03-15
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 2020-02-28
    相关资源
    最近更新 更多