首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用using加密,需要使用crypto_box_keypair生成公钥和私钥

使用using加密,需要使用crypto_box_keypair生成公钥和私钥
EN

Stack Overflow用户
提问于 2021-04-25 08:59:13
回答 1查看 758关注 0票数 1

我一直在与library库合作来实现Shamir秘密共享,并试图测试由暗水晶完成的实现。

https://gitlab.com/dark-crystal-javascript/key-backup-crypto/-/blob/master/example.js

实现是这样的

代码语言:javascript
复制
function encryptionKeypair () {
    const keypair = {
      publicKey: sodium.sodium_malloc(sodium.crypto_box_PUBLICKEYBYTES),
      secretKey: sodium.sodium_malloc(sodium.crypto_box_SECRETKEYBYTES)
    }
    sodium.crypto_box_keypair(keypair.publicKey, keypair.secretKey)
    return keypair
  },

 function oneWayBox (message, publicKey) {
    console.log('in one way box');
    const curvePublicKey = sodium.sodium_malloc(sodium.crypto_box_PUBLICKEYBYTES)
    // console.log('curvePublicKey', curvePublicKey.toString('hex'));
    console.log('curvePublicKey', curvePublicKey.length);
    console.log('publicKey', publicKey.length);
    
    sodium.crypto_sign_ed25519_pk_to_curve25519(curvePublicKey, publicKey)

    // console.log('curvePublicKey', curvePublicKey.toString('hex'));


    console.log('in one way box');
    console.log('\n');

    const ephemeral = this.encryptionKeypair()
    const nonce = this.randomBytes(sodium.crypto_box_NONCEBYTES)
    const cipherText = sodium.sodium_malloc(message.length + sodium.crypto_box_MACBYTES)
  
    sodium.crypto_box_easy(cipherText, message, nonce, curvePublicKey, ephemeral.secretKey)
    zero(ephemeral.secretKey)
    zero(message)
    return Buffer.concat([nonce, ephemeral.publicKey, cipherText])
  },

下面是秘密共享-generation.js

代码语言:javascript
复制
const secrets = require('secret-sharing')
const s = require('.')

const secret = 'My secret key'
const label = ''

console.log('Secret to share:', secret.toString('hex'))

console.log(`Packing with label: '${label}'`)
const packedSecret = s.packLabel(secret, label)
console.log(`Packed secret: ${packedSecret.toString('hex')}`)
console.log(`Length of packed secret is ${packedSecret.length} bytes.`)
const signingKeypair = s.keypair()
const encryptionKeypair = s.signingKeypairToEncryptionKeypair(signingKeypair)

const custodians = []
for (let i = 0; i < 5; i++) {
  custodians.push(s.encryptionKeypair())
}


console.log('custodians', custodians);

console.log('Creating 5 shares, 3 needed to recover')
secrets.share(packedSecret, 5, 3).then((shards) => {
  console.log('Shards:')
  console.log(shards.map(s => s.toString('hex')))
  console.log('Signed shards:')
  const signedShards = s.signShards(shards, signingKeypair)
  console.log(signedShards.map(s => s.toString('hex')))

  const boxedShards = signedShards.map((shard, i) => {
    return s.oneWayBox(shard, custodians[i].publicKey)
  })

  console.log('Boxed shards:')
  console.log(boxedShards.map(s => s.toString('hex')))
  console.log(`Length of boxed shards are ${boxedShards[0].length} bytes.`)
  secrets.combine(shards.slice(2)).then((result) => {
    console.log('Result of recombining 3 shares:', result.toString())
  })
})

现在的问题是,当我使用encryptionKeypair函数来生成密钥对时,然后当我试图使用在这个encryptionKeypair函数中生成的密钥对来生成crypto_sign_ed25519_sk_to_curve25519时,我将得到

UnhandledPromiseRejectionWarning: Error: ENOMEM, Cannot allocate memory

我检查了我的交换空间,它是完全免费的

代码语言:javascript
复制
           total        used        free      shared  buff/cache   available
Mem:           3138          83        2896           0         158        2908
Swap:          5119           0        5119

我不明白问题是什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-25 12:28:56

我不清楚为什么要将用encryptionKeypair()创建的密钥对与crypto_sign_ed25519_sk_to_curve25519()crypto_sign_ed25519_pk_to_curve25519()进行转换。

后两种方法将秘密或公共Ed25519密钥(用于签名上下文)转换为秘密或公共X25519密钥(用于密钥交换上下文)。

encryptionKeypair()应用crypto_box_keypair(),因此已经创建了一个X25519密钥对,因此转换是不必要的(也是不可能的)。

转换方法的有效使用将是,例如使用crypto_sign_keypair(),它生成一个Ed25519密钥对:

代码语言:javascript
复制
var sodium = require('sodium-native');
...
var ed25519KeyPair = signingKeypair() // Create an Ed25519 keypair
var x25519KeyPair = {
    publicKey: sodium.sodium_malloc(sodium.crypto_box_PUBLICKEYBYTES),
    secretKey: sodium.sodium_malloc(sodium.crypto_box_SECRETKEYBYTES)
}
sodium.crypto_sign_ed25519_pk_to_curve25519(x25519KeyPair.publicKey, ed25519KeyPair.publicKey) // Convert the public Ed25519 into a public X25519 key
sodium.crypto_sign_ed25519_sk_to_curve25519(x25519KeyPair.secretKey, ed25519KeyPair.secretKey) // Convert the secret Ed25519 into a secret X25519 key
console.log(x25519KeyPair.publicKey)
console.log(x25519KeyPair.secretKey)

function signingKeypair () {
    const keypair = {
        publicKey: sodium.sodium_malloc(sodium.crypto_sign_PUBLICKEYBYTES),
        secretKey: sodium.sodium_malloc(sodium.crypto_sign_SECRETKEYBYTES)
    }
    sodium.crypto_sign_keypair(keypair.publicKey, keypair.secretKey)
    return keypair
}

另外,我无法复制发布的错误消息。当使用encryptionKeypair()而不是signingKeypair()时,我得到以下错误消息错误:公钥转换失败。

编辑:

在第二个代码片段中,custodians的密钥对是用s.encryptionKeypair()创建的,它生成X25519密钥对。在后者称为s.oneWayBox()中,然后尝试使用crypto_sign_ed25519_pk_to_curve25519()来转换公钥,这必须如上面所描述的那样失败。

这大概是个虫子吧!一个可能的解决方法是使用custodians(或signingKeypair())生成s.keypair() (或signingKeypair())密钥对,这将创建Ed25519密钥对。然后,可以在X25519中成功地将公钥转换为s.oneWayBox()密钥。通过此更改,oneWayBox()在我的机器上运行时不会出现任何错误。

对Ed25519密钥对的这一更改也与encryptionKeypair()的描述相一致,该描述指出,该方法仅用于生成临时密钥时,例如在oneWayBox()中。在所有其他情况下,它都是从Ed25519键内部派生的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67251547

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档