混合tweetnacl.js和tweetnaclfast(java)进行非对称加密

ohtdti5x  于 2021-07-05  发布在  Java
关注(0)|答案(1)|浏览(446)

我们的项目是使用非对称加密 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-nacljvm 但看起来 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 .

7gcisfzg

7gcisfzg1#

TweetJava是TweetJS的一个端口。因此,可以预期两者提供相同的功能。至少对于posted方法是这样的,它可以在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=

java端的加密使用 encrypt 方法张贴在上面(和 publicKeyJS ):

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>

相关问题