kotlin中的文件加密返回header_too_long
我正在将旧的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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我可以重现“ 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.