我需要使用用户的公钥对消息进行加密. 用户将接收到该消息,并且将不得不使用私钥对其进行解密.我试了所有的方法,但我不知道我做错了什么. 我创建了一个独立运行的 node 脚本,只安装了两个必要的依赖项(tweetnacl和tweetnacl-utils). 显然,消息是正确加密的,但当我try 解密它时,DECRYPTED_MESSAGE常量为"NULL".

我已经使用这两个库来对消息进行签名,并且签名部分工作得很好,所以我不打算转换库.你能告诉我我做错了什么吗?这是您可以使用Node.js 运行的代码

const nacl = require('tweetnacl');
const naclUtil = require('tweetnacl-util');

// Getting keypair from a key
const x25519_from_key = (key) => {
    console.log(key.length)
    const boxKeyPair = nacl.box.keyPair.fromSecretKey(key);
    const secretKey = boxKeyPair.secretKey;
    const publicKey = boxKeyPair.publicKey;

    const result = {
        publicKey:
        {
            uint: publicKey,
            base64: naclUtil.encodeBase64(publicKey)
        },
        secretKey: {
            uint: secretKey,
            base64: naclUtil.encodeBase64(secretKey)
        }
    }

    return result;
};

// Encrypt a message using the public key
const encryptMessage = (message, x25519_public_uint) => {

    const nonce = nacl.randomBytes(nacl.box.nonceLength);
    const message_decoded = naclUtil.decodeUTF8(message);

    const encrypted_message = nacl.box.after(
        message_decoded,
        nonce,
        x25519_public_uint
    );

    return {
        nonce_base64: naclUtil.encodeBase64(nonce),
        encrypted_message_encoded: naclUtil.encodeBase64(encrypted_message),
    };
};

// Decrypt message using the secret key
const decryptMessage = (encrypted_message, nonce_base64, x25519_secret_key) => {

  
    const nonce = naclUtil.decodeBase64(nonce_base64);
    const encrypted_message_decoded = naclUtil.decodeBase64(encrypted_message);
  
    const decrypted_message = nacl.box.open.after(
      encrypted_message_decoded,
      nonce,
      x25519_secret_key
    );


    return naclUtil.encodeUTF8(decrypted_message);
  };
  

// Generating keypair x25519
const keyPair = x25519_from_key(nacl.randomBytes(nacl.box.secretKeyLength));

// Encrypt with publicKey
const message = 'This is a plain message';
const encrypted = encryptMessage(message, keyPair.publicKey.uint);


console.log('Original message:', message);

// Show encrypted message
console.log('Encrypted message:', encrypted.encrypted_message_encoded);
console.log('Nonce:', encrypted.nonce_base64);


// Show decrypted message
const decrypted = decryptMessage(encrypted.encrypted_message_encoded, encrypted.nonce_base64, keyPair.secretKey.uint);
console.log('Decrypted message:', decrypted);

推荐答案

在加密或解密时,必须使用自己的私钥和对方的公钥.下面的工作代码显示了这一点,该代码基本上基于您的代码:

var naclUtil = nacl.util

// Getting keypair from a key
const x25519_from_key = (key) => {
    console.log(key.length)
    const boxKeyPair = nacl.box.keyPair.fromSecretKey(key);
    const secretKey = boxKeyPair.secretKey;
    const publicKey = boxKeyPair.publicKey;

    const result = {
        publicKey:
        {
            uint: publicKey,
            base64: naclUtil.encodeBase64(publicKey)
        },
        secretKey: {
            uint: secretKey,
            base64: naclUtil.encodeBase64(secretKey)
        }
    }

    return result;
};

// Encrypt message using the own secret key and the public key of the other side
const encryptMessage = (message, x25519_public_uint, x25519_secret_key) => {

    const nonce = nacl.randomBytes(nacl.box.nonceLength);
    const message_decoded = naclUtil.decodeUTF8(message);

    const encrypted_message = nacl.box(
        message_decoded,
        nonce,
        x25519_public_uint,
        x25519_secret_key
    );

    return {
        nonce_base64: naclUtil.encodeBase64(nonce),
        encrypted_message_encoded: naclUtil.encodeBase64(encrypted_message),
    };
};

// Decrypt message using the own secret key and the public key of the other side
const decryptMessage = (encrypted_message, nonce_base64, x25519_public_uint, x25519_secret_key) => {
  
    const nonce = naclUtil.decodeBase64(nonce_base64);
    const encrypted_message_decoded = naclUtil.decodeBase64(encrypted_message);
    const decrypted_message = nacl.box.open(
      encrypted_message_decoded,
      nonce,
      x25519_public_uint,
      x25519_secret_key
    );

    return naclUtil.encodeUTF8(decrypted_message);
  };
  

// Generating keypair x25519 for A and B side
const keyPairA = x25519_from_key(nacl.randomBytes(nacl.box.secretKeyLength));
const keyPairB = x25519_from_key(nacl.randomBytes(nacl.box.secretKeyLength));

// A side: Encrypt message using the own secret key (A side) and the public key of the other side (B side)
const message = 'This is a plain message';
const encrypted = encryptMessage(message, keyPairB.publicKey.uint, keyPairA.secretKey.uint);

console.log('Original message:', message);

// Show encrypted message
console.log('Encrypted message:', encrypted.encrypted_message_encoded);
console.log('Nonce:', encrypted.nonce_base64);


// B side: Decrypt message using the own secret key (B side) and the public key of the other side (A side)
const decrypted = decryptMessage(encrypted.encrypted_message_encoded, encrypted.nonce_base64, keyPairA.publicKey.uint, keyPairB.secretKey.uint);
console.log('Decrypted message:', 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-fast.min.js"></script>

您的代码的主要区别在于,这里发布的代码使用nacl.box()(而不是nacl.box.after())进行加密,使用nacl.box.open()(而不是nacl.box.open.after())进行解密.

NaC l/LibNa允许确定共享秘密(before()种方法)和要执行的加密/解密(after()种方法)separately,参见TweetNaCl文档中的here或LibNa文档中更详细的here.

在您的代码中,after()个方法的应用不正确(after()个需要共享密钥,而共享密钥又必须由before()个方法确定).

Javascript相关问答推荐

如何在JavaScript中在文本内容中添加新行

react/redux中的formData在expressjs中返回未定义的req.params.id

类型脚本中只有字符串或数字键而不是符号键的对象

无法在nextjs应用程序中通过id从mongoDB删除'

. NET中Unix时间转换为日期时间的奇怪行为

使用useEffect,axios和useParams进行react测试

如何为我的astro页面中的相同组件自动创建不同的内容?

如何将Openjphjs与next.js一起使用?

Web Crypto API解密失败,RSA-OAEP

扩展类型的联合被解析为基类型

使用带有HostBinding的Angular 信号来更新样式?

react 路由如何使用从加载器返回的数据

Chart.js Hover线条在鼠标离开时不会消失

如何在Reaction中设置缺省值, Select 下拉列表,动态追加剩余值?

如何使pdf.js上的文本呈现为可选?

在此div中添加一个类,并在一段时间后在Java脚本中将其删除

使用Java脚本在div中创建新的span标记

由于http.get,*ngIf的延迟很大

JavaScript -如何跳过某个字符(S)来打乱字符串中的字符

使用JavaScript或PHP从div ID值创建锚标记和链接