简体   繁体   English

Java 加密 API 对比不同平台

[英]Java crypto API vs. different platforms

I have an Android application, which uses javax.crypto to encrypt some text data in files.我有一个 Android 应用程序,它使用javax.crypto加密文件中的一些文本数据。 Encryption implementation is similar to this .加密实现与类似。 The application works fine with the encrypted data it previously created.该应用程序可以很好地处理它之前创建的加密数据。

Now, I almost ported my Android application to desktop (JFace/SWT).现在,我几乎将我的 Android 应用程序移植到桌面 (JFace/SWT)。 I'm using the same encryption implementation for the ported application, as it does not depend on any Android-specific API.我对移植的应用程序使用相同的加密实现,因为它不依赖于任何特定于 Android 的 API。 The ported application works fine with encrypted data it created.移植的应用程序可以很好地处理它创建的加密数据。

The problem is that desktop application cannot decrypt data, which was saved with Android application.问题是桌面应用程序无法解密使用 Android 应用程序保存的数据。 The Android application fails to decrypt data, which was saved with desktop application as well. Android 应用程序无法解密数据,该数据也与桌面应用程序一起保存。 I double checked bytes streams of plain data and password to encrypt on both platforms.我仔细检查了纯数据和密码的字节流,以便在两个平台上进行加密。 They are the same, so there are no problems with text encoding or so.它们是相同的,因此文本编码左右没有问题。 But encryption routine return different encrypted results on different platforms even input data is byte-to-byte identical.但是加密程序在不同的平台上返回不同的加密结果,即使输入数据是字节到字节相同的。

Does Java crypto API guarantees the same operation on different platforms? Java 加密 API 是否保证不同平台上的操作相同? Should an encryption provider (AES/128bit in my case) work the same way on Android, Linux and Windows?加密提供程序(在我的情况下为 AES/128 位)是否应该在 Android、Linux 和 Windows 上以相同的方式工作? Is there a way to tune javax.crypto to get interoperability on different platforms?有没有办法调整javax.crypto以获得不同平台上的互操作性?

AES-128 should work the same on both systems. AES-128 在两个系统上的工作方式应该相同。 In theory.理论上。

In practice there are a lot of details that need to be the same on both systems.在实践中,两个系统有很多细节需要相同。

  • are you using the same padding at both sides?您是否在两侧使用相同的填充?
  • are you using the same mode (CBC, CTR, ECB) at both sides?您是否在双方都使用相同的模式(CBC,CTR,ECB)?
  • do you have exactly the same password at both sides?双方的密码是否完全相同
  • do you have the same IV/Nonce at both sides?两边的 IV/Nonce 是否相同?
  • do you have the same key derivation method on both sides?双方是否有相同的密钥派生方法?

Check any defaults on both systems.检查两个系统上的任何默认值。 If the defaults don't match then you will need to set one side or the other explicitly.如果默认值不匹配,那么您将需要明确设置一侧或另一侧。

It is a mistake to depend on a cryptographically-random number generator generating the same random numbers on different platforms.依赖加密随机数生成器在不同平台上生成相同的随机数是错误的。 Normally, the cryptographic random salt used in a key-derivation algorithm has to be communicated from sender to receiver.通常,密钥派生算法中使用的加密随机盐必须从发送方传递到接收方。 It might be communicated as a secret, but it does need to be communicated.它可能会作为秘密传达,但确实需要传达。 The "master password" is the main secret, of course.当然,“主密码”是主要秘密。

One way these salts are often communicated is as a prefix on the ciphertext.这些盐经常被传达的一种方式是作为密文的前缀。 That makes the ciphertext longer than the plaintext, but I don't think that matters in your sample technique.这使得密文比明文长,但我认为这在您的示例技术中并不重要。

Also, for a full-up encrypted-message exchange, other parameters of the encryption need to be communicated to the decrypter.此外,对于完整的加密消息交换,需要将加密的其他参数传达给解密器。 You can wire those into your implementations, as you've done here, but depending on reproducibility seems too brittle.您可以将它们连接到您的实现中,就像您在此处所做的那样,但是取决于可重复性似乎太脆弱了。 It is of course something an attacker can replicate, of course, so it is not part of your secret.当然,攻击者可以复制它,所以它不是你的秘密的一部分。

You might want to rethink the key-generation algorithm setup to be something more robust.您可能需要重新考虑密钥生成算法设置,使其更加健壮。

Afterthought: What is happening in the current approach is a cryptographically-useful RNG is being used in a way where all the randomness has been removed.事后思考:当前方法中发生的情况是,一种加密有用的 RNG 正在以一种已消除所有随机性的方式使用。 The recommendation to check out PBKDF2 and key-derivation generally is a good one.检查 PBKDF2 和密钥派生的建议通常是一个很好的建议。

You'd have to show us some code.您必须向我们展示一些代码。 One frequent beginner mistake is to store the encrypted data in a String rather than the byte[] it came in. String isn't a container for binary data.一个常见的初学者错误是将加密数据存储在 String 而不是它进来的 byte[] 中。String 不是二进制数据的容器。 This technique can fail in many ways including default charade differences.这种技术可能会以多种方式失败,包括默认的字谜差异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM