如何解决将tweetnacl.js与TweetNaclFastjava混合以进行非对称加密
我们的项目正在使用带有nacl.Box
和临时密钥的非对称加密:
encrypt(pubKey,msg) {
if (typeof msg !== 'string') {
msg = JSON.stringify(msg)
}
let ephemKeys = nacl.Box.keyPair()
let msgArr = nacl.util.decodeUTF8(msg)
let nonce = nacl.randomBytes(nacl.Box.nonceLength)
p(`naclrsa.pubKey=${this.pubKey}`)
let encrypted = nacl.Box(
msgArr,nonce,nacl.util.decodeBase64(pubKey),ephemKeys.secretKey
)
let nonce64 = nacl.util.encodeBase64(nonce)
let pubKey64 = nacl.util.encodeBase64(ephemKeys.publicKey)
let encrypted64 = nacl.util.encodeBase64(encrypted)
return {nonce: nonce64,ephempubKey: pubKey64,encrypted: encrypted64}
}
我们目前有node.js
个应用程序,可以对这些消息进行解密。我们希望为某些功能使用jvm
语言。 tweet-nacl
上似乎没有jvm
的老牌玩家,但似乎
-
tweetnacl-java
https://github.com/InstantWebP2P/tweetnacl-java
及其推荐的实现方式
°tweetnacl-fast
https://github.com/InstantWebP2P/tweetnacl-java/blob/master/src/main/java/com/iwebpp/crypto/TweetNaclFast.java
是受欢迎的。
目前尚不清楚该库中使用临时密钥进行asymmetric
加密的类似方式。支持吗?请注意,如果java
不支持kotlin
或tweetnacl-java
,我将开放。
解决方法
tweetnacl-java是tweetnacl-js的端口。因此,期望两者都提供相同的功能。至少对于发布的方法是这种情况,可以在Java端使用 TweetNaclFast 如下实现:
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import com.iwebpp.crypto.TweetNaclFast;
import com.iwebpp.crypto.TweetNaclFast.Box;
import com.iwebpp.crypto.TweetNaclFast.Box.KeyPair;
...
private static EncryptedData encrypt(byte[] pubKey,String msg) {
KeyPair ephemKeys = Box.keyPair();
byte[] msgArr = msg.getBytes(StandardCharsets.UTF_8);
byte[] nonce = TweetNaclFast.randombytes(Box.nonceLength);
Box box = new Box(pubKey,ephemKeys.getSecretKey());
byte[] encrypted = box.box(msgArr,nonce);
String nonce64 = Base64.getEncoder().encodeToString(nonce);
String ephemPubKey64 = Base64.getEncoder().encodeToString(ephemKeys.getPublicKey());
String encrypted64 = Base64.getEncoder().encodeToString(encrypted);
return new EncryptedData(nonce64,ephemPubKey64,encrypted64);
}
...
class EncryptedData {
public EncryptedData(String nonce,String ephemPubKey,String encrypted) {
this.nonce = nonce;
this.ephemPubKey = ephemPubKey;
this.encrypted = encrypted;
}
public String nonce;
public String ephemPubKey;
public String encrypted;
}
为了证明双方都兼容,下面将在Java方面对纯文本进行加密,然后在JavaScript方面对纯文本进行解密:
-
首先,在JavaScript端需要一个密钥对,其公钥(
publicKeyJS
)被传递到Java端。 JavaScript端的密钥对可以如下生成:let keysJS = nacl.box.keyPair(); let secretKeyJS = keysJS.secretKey; let publicKeyJS = keysJS.publicKey; console.log("Secret key: " + nacl.util.encodeBase64(secretKeyJS)); console.log("Public key: " + nacl.util.encodeBase64(publicKeyJS));
具有以下示例输出:
Secret key: YTxAFmYGm4yV2OP94E4pcD6LSsN4gcSBBAlU105l7hw= Public key: BDXNKDHeq0vILm8oawAGAQtdIsgwethzBTBqmsWI+R8=
-
然后使用上面发布的
encrypt
方法(和publicKeyJS
)在Java端进行加密:byte[] publicKeyJS = Base64.getDecoder().decode("BDXNKDHeq0vILm8oawAGAQtdIsgwethzBTBqmsWI+R8="); EncryptedData encryptedFromJava = encrypt(publicKeyJS,"I've got a feeling we're not in Kansas anymore..."); System.out.println("Nonce: " + encryptedFromJava.nonce); System.out.println("Ephemeral public key: " + encryptedFromJava.ephemPubKey); System.out.println("Ciphertext: " + encryptedFromJava.encrypted);
具有以下示例输出:
Nonce: FcdzXfYwSbI0nq2WXsLe9aAh94vXSoWd Ephemeral public key: Mde+9metwF1jIEij5rlZDHjAStR/pd4BN9p5JbZleSg= Ciphertext: hHo7caCxTU+hghcFZFv+djAkSlWKnC12xj82V2R/Iz9GdOMoTzjoCDcz9m/KbRN6i5dkYi3+Gf0YTtKlZQWFooo=
-
JS端的解密给出原始明文(使用
secretKeyJS
):let nonce = "FcdzXfYwSbI0nq2WXsLe9aAh94vXSoWd"; let ephemPubKey = "Mde+9metwF1jIEij5rlZDHjAStR/pd4BN9p5JbZleSg="; let encrypted = "hHo7caCxTU+hghcFZFv+djAkSlWKnC12xj82V2R/Iz9GdOMoTzjoCDcz9m/KbRN6i5dkYi3+Gf0YTtKlZQWFooo="; let secretKeyJS = nacl.util.decodeBase64("YTxAFmYGm4yV2OP94E4pcD6LSsN4gcSBBAlU105l7hw="); let decryptedFromJS = decrypt(secretKeyJS,{nonce: nonce,ephemPubKey: ephemPubKey,encrypted: encrypted}); console.log(nacl.util.encodeUTF8(decryptedFromJS)); // I've got a feeling we're not in Kansas anymore... function decrypt(secretKey,ciphertext){ let decrypted = nacl.box.open( nacl.util.decodeBase64(ciphertext.encrypted),nacl.util.decodeBase64(ciphertext.nonce),nacl.util.decodeBase64(ciphertext.ephemPubKey),secretKey ); return decrypted; }
<script src="https://cdn.jsdelivr.net/npm/tweetnacl-util@0.15.1/nacl-util.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/tweetnacl@1.0.3/nacl.min.js"></script>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。