kotlin中的文件加密返回header_too_long

发布于 2025-02-03 10:44:43 字数 3482 浏览 3 评论 0原文

我正在将旧的Java Android应用程序移植到Kotlin方法中。 我要在这里要实现的目标是使用.der文件

在此处加密文件,因为您可以看到我基本上将代码调整为在Kotlin Base

Kotlin

    val encodedKey : ByteArray = ByteArray((publicKeyFile.length()).toInt())
    val publicKeyFileIS = FileInputStream(publicKeyFile)
    publicKeyFileIS.read(encodedKey)

    // create public key
    val publicKeySpec = X509EncodedKeySpec(encodedKey)
    val kf = KeyFactory.getInstance("RSA")
    val pk = kf.generatePublic(publicKeySpec)

Java

    byte[] encodedKey = new byte[(int)publicKeyFile.length()];
    FileInputStream publicKeyFileIS = new FileInputStream(publicKeyFile);
    publicKeyFileIS.read(encodedKey);
    
    // create public key
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PublicKey pk = kf.generatePublic(publicKeySpec);

中工作,问题是在Java App中,加密就像魅力一样,但是在我尝试启动时在Kotlin中

genatePublic

i获得

错误:0C00007B:ASN.1编码例程:OpenSSL_Internal:Header_too_long

有任何暗示如何解决此问题?

编辑:我的.der有此内容

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1pHArx4xPIMGDI53itcMEx1hNXRmllyTmrsB
dFNjRVeXwHrfKtNVruUR12SU1PeM7jQ4fmHJLcy4BBWgYpktylLM9xyVyXVqsqOZPuvnvqt/mUABXAVW
odkW/oANbSgbBnvLwVmuX+dNnMKIp1RMY/xEstYx4HaVUsClaSZpxuMdkfOYP9tQs5uNbR5RyWE6+4JE
2fkhpwK82HIX94wGvSoiNCgBcXQPjYZf1TnZHifv7FbuRiZxjzdKgtqgBT8tUW8m5Mjz4ktN8YkHov8a
XRhbkXbBdN8LBjxyDs3M7dm3W3/u3pLN3WtkDXuREGNQNUi3/PU93JK9IzuUDWwF2wIDAQAB

编辑2: 我试图将方法readbytes()和记录.der的base64录制,该方法相当不同

MO+/vQEiMA0GCSrvv71I77+977+9DQEBAQUAA++/vQEPADDvv70BCgLvv70BAQDWke+/vR4xPO+/vQYM77+9d++/ve+/vQwTHWE1dGbvv71c77+977+977+9AXRTY0VX77+977+9eu+/vSrvv71V77+977+9Ee+/vWTvv73vv73vv73vv700OH5h77+9Lcy4BBXvv71i77+9Le+/vVLvv73vv70c77+977+9dWrvv73vv73vv70+77+9576rf++/vUABXAVW77+977+9Fu+/ve+/vQ1tKBsGe++/ve+/vVnvv71f77+9Te+/vcKI77+9VExj77+9RO+/ve+/vTHvv71277+9Uu+/vWkmae+/ve+/vR3vv73vv70/77+9UO+/ve+/ve+/vW0eUe+/vWE677+9RO+/ve+/vSHvv70C77+977+9chfvv70G77+9KiI0KAFxdA/vv73vv71f77+9Oe+/vR4n77+977+9Vu+/vUYmce+/vTdK77+92qAFPy1Rbybvv73vv73vv73vv71LTe+/vQfvv73vv70aXRhb77+9du+/vXTvv70LBjxyDu+/ve+/ve+/vdm3W3/vv73eku+/ve+/vWtkDXvvv70QY1A1SO+/ve+/ve+/vT3cku+/vSM777+9DWwF77+9AgMBAAE=

,并且代码:

val encodedKey = FileInputStream(publicKeyFile).readBytes()
        val encodedString: String = Base64.getEncoder().encodeToString(encodedKey)
        println("publicKeyFile keyBase64 : $encodedString")

        // create public key
        val publicKeySpec = X509EncodedKeySpec(encodedKey)
        val kf = KeyFactory.getInstance("RSA")
        val pk = kf.generatePublic(publicKeySpec)

编辑3:

这里有关Gradle文件

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
    jvmTarget = '1.8'
}

和stackTrace的一些信息:

java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0c00007b:ASN.1 encoding routines:OPENSSL_internal:HEADER_TOO_LONG
at com.android.org.conscrypt.OpenSSLKey.getPublicKey(OpenSSLKey.java:290)
W/System.err: at com.android.org.conscrypt.OpenSSLRSAKeyFactory.engineGeneratePublic(OpenSSLRSAKeyFactory.java:54)
W/System.err: at java.security.KeyFactory.generatePublic(KeyFactory.java:357)
W/System.err: at it.lynx.gmelibrary.utils.FileEncryption.saveKey(FileEncryption.kt:95)

i'm porting an old java android app to a kotlin approach.
What i'm trying to achieve here is to encrypt a file using a .der file

Here what i did so far, as you can see i basically adapted the code to work in a kotlin base

Kotlin

    val encodedKey : ByteArray = ByteArray((publicKeyFile.length()).toInt())
    val publicKeyFileIS = FileInputStream(publicKeyFile)
    publicKeyFileIS.read(encodedKey)

    // create public key
    val publicKeySpec = X509EncodedKeySpec(encodedKey)
    val kf = KeyFactory.getInstance("RSA")
    val pk = kf.generatePublic(publicKeySpec)

Java

    byte[] encodedKey = new byte[(int)publicKeyFile.length()];
    FileInputStream publicKeyFileIS = new FileInputStream(publicKeyFile);
    publicKeyFileIS.read(encodedKey);
    
    // create public key
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PublicKey pk = kf.generatePublic(publicKeySpec);

The problem is that in the Java app, the encryption works like a charm, but in kotlin one when i try to launch

generatePublic

I get

error:0c00007b:ASN.1 encoding routines:OPENSSL_internal:HEADER_TOO_LONG

Any hint on how to solve this?

EDIT: my .der has this content

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1pHArx4xPIMGDI53itcMEx1hNXRmllyTmrsB
dFNjRVeXwHrfKtNVruUR12SU1PeM7jQ4fmHJLcy4BBWgYpktylLM9xyVyXVqsqOZPuvnvqt/mUABXAVW
odkW/oANbSgbBnvLwVmuX+dNnMKIp1RMY/xEstYx4HaVUsClaSZpxuMdkfOYP9tQs5uNbR5RyWE6+4JE
2fkhpwK82HIX94wGvSoiNCgBcXQPjYZf1TnZHifv7FbuRiZxjzdKgtqgBT8tUW8m5Mjz4ktN8YkHov8a
XRhbkXbBdN8LBjxyDs3M7dm3W3/u3pLN3WtkDXuREGNQNUi3/PU93JK9IzuUDWwF2wIDAQAB

Edit 2:
I tried to put the method readBytes() and logging a base64 of the .der, which is fairly different

MO+/vQEiMA0GCSrvv71I77+977+9DQEBAQUAA++/vQEPADDvv70BCgLvv70BAQDWke+/vR4xPO+/vQYM77+9d++/ve+/vQwTHWE1dGbvv71c77+977+977+9AXRTY0VX77+977+9eu+/vSrvv71V77+977+9Ee+/vWTvv73vv73vv73vv700OH5h77+9Lcy4BBXvv71i77+9Le+/vVLvv73vv70c77+977+9dWrvv73vv73vv70+77+9576rf++/vUABXAVW77+977+9Fu+/ve+/vQ1tKBsGe++/ve+/vVnvv71f77+9Te+/vcKI77+9VExj77+9RO+/ve+/vTHvv71277+9Uu+/vWkmae+/ve+/vR3vv73vv70/77+9UO+/ve+/ve+/vW0eUe+/vWE677+9RO+/ve+/vSHvv70C77+977+9chfvv70G77+9KiI0KAFxdA/vv73vv71f77+9Oe+/vR4n77+977+9Vu+/vUYmce+/vTdK77+92qAFPy1Rbybvv73vv73vv73vv71LTe+/vQfvv73vv70aXRhb77+9du+/vXTvv70LBjxyDu+/ve+/ve+/vdm3W3/vv73eku+/ve+/vWtkDXvvv70QY1A1SO+/ve+/ve+/vT3cku+/vSM777+9DWwF77+9AgMBAAE=

and the code:

val encodedKey = FileInputStream(publicKeyFile).readBytes()
        val encodedString: String = Base64.getEncoder().encodeToString(encodedKey)
        println("publicKeyFile keyBase64 : $encodedString")

        // create public key
        val publicKeySpec = X509EncodedKeySpec(encodedKey)
        val kf = KeyFactory.getInstance("RSA")
        val pk = kf.generatePublic(publicKeySpec)

Edit 3:

here some info about the gradle file

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
    jvmTarget = '1.8'
}

And the stacktrace:

java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0c00007b:ASN.1 encoding routines:OPENSSL_internal:HEADER_TOO_LONG
at com.android.org.conscrypt.OpenSSLKey.getPublicKey(OpenSSLKey.java:290)
W/System.err: at com.android.org.conscrypt.OpenSSLRSAKeyFactory.engineGeneratePublic(OpenSSLRSAKeyFactory.java:54)
W/System.err: at java.security.KeyFactory.generatePublic(KeyFactory.java:357)
W/System.err: at it.lynx.gmelibrary.utils.FileEncryption.saveKey(FileEncryption.kt:95)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请恋爱 2025-02-10 10:44:43

我可以重现“ ASN.1编码例程:openssl_internal:header_too_long”错误时,当我尝试解析损坏的“ mo+/vqei ... agmbaae =” content(base-64解码后)。

我相信问题是您的Kotlin正在阅读与Java不同的(不良)文件。在两种情况下,公共密钥文件都应相同,并且应进行编码(即“二进制”,而不是基本64编码)。

您可以通过将相同的基本-64编码键与代码示例中的字符串文字放置并在运行时解码,而不是从文件中加载来验证这一点。如果两个样本都起作用,您将知道这是一个数据问题,而不是代码问题。

我可以通过解码der-der编码的密钥来像使用UTF-8的文本一样,将您的公钥转换为损坏的“ mo+/vqei ... agmbaae =”形式,然后重新编码带有UTF-8的文字。区别在于出现的替换字符数量。

看起来UTF-8解码(首先损坏了内容)可能没有使用Java进行,但是处理畸形输入的某些内容略有不同。一个畸形的序列,例如“…  c0  af …”看起来像是代码点u+004f('o'o')错误地编码为两个UTF-8字节。 (这是错误的,因为它必须编码为单个字节0x4f。)Java为每个字节输出一个替换字符。看起来您使用的解码器仅用于无效序列的一个替换字符。

I can reproduce the "ASN.1 encoding routines:OPENSSL_internal:HEADER_TOO_LONG" error when I try to parse the corrupted "MO+/vQEi ... AgMBAAE=" content (after base-64 decoding).

I believe the problem is that your Kotlin is reading a different (bad) file than your Java. The public key file should be identical in both cases, and should be DER-encoded (that is, "binary", not base-64–encoded).

You could verify this by putting the same base-64–encoded key as a string literal in both code samples and decoding it at runtime, instead of loading from a file. If both samples work, you'll know it's a data problem, not a code problem.

I can almost convert your public key into the corrupt "MO+/vQEi ... AgMBAAE=" form by decoding the DER-encoded key as if it were text using UTF-8, then re-encoding the text with UTF-8. The difference is in the number of replacement characters that show up.

It looks like the UTF-8 decoding (where the content was first corrupted) may not have been done with Java, but something that handles malformed inputs a little differently. A malformed sequence like "… C0 AF …" looks like the code point U+004F ('O') incorrectly encoded as two UTF-8 bytes. (That's wrong because it must be encoded as a single byte, 0x4F.) Java outputs a replacement character for each byte. It looks like the decoder you used outputs just one replacement character for the invalid sequence.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文