首页 > 解决方案 > Android+crypto:导出公钥,使用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) 

标签: androidencryptionopensslrsa

解决方案


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


推荐阅读