GitHub API secret encryption with libsodium in Node.js: UnhandledPromiseRejectionWarning: Error: bad public key size
GitHub API secret encryption with libsodium in Node.js: UnhandledPromiseRejectionWarning: Error: bad public key size
我想通过 GitHub REST API 设置存储库机密。我使用 docs:
中的示例
const sodium = require('tweetsodium');
const key = "base64-encoded-public-key";
const value = "plain-text-secret";
// Convert the message and key to Uint8Array's (Buffer implements that interface)
const messageBytes = Buffer.from(value);
const keyBytes = Buffer.from(key, 'base64');
// Encrypt using LibSodium.
const encryptedBytes = sodium.seal(messageBytes, keyBytes);
// Base64 the encrypted secret
const encrypted = Buffer.from(encryptedBytes).toString('base64');
console.log(encrypted);
我收到此错误:
(node:6008) UnhandledPromiseRejectionWarning: Error: bad public key size
at checkBoxLengths (C:\Users\User\probot\node_modules\tweetnacl\nacl-fast.js:2158:54)
at Function.nacl.box.before (C:\Users\User\probot\node_modules\tweetnacl\nacl-fast.js:2231:3)
at Object.nacl.box (C:\Users\User\probot\node_modules\tweetnacl\nacl-fast.js:2225:20)
at Object.tweetSodium.seal (C:\Users\User\probot\node_modules\tweetsodium\dist\index.umd.js:53:33)
at createSecret (C:\Users\User\probot\src\service\secret.js:55:33)
at Object.<anonymous> (C:\Users\User\probot\src\service\secret.js:73:1)
at Module._compile (internal/modules/cjs/loader.js:1138:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
at Module.load (internal/modules/cjs/loader.js:986:32)
at Function.Module._load (internal/modules/cjs/loader.js:879:14)
(node:6008) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:6008) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
问题:我如何正确地加密和解密秘密以便我可以在我的 API 中使用它?
解决方案:@Topaco提到您需要使用base64编码的密钥,例如2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvvcCU=
。这解决了上述错误。
编辑
我将在不同的存储库中使用不同的秘密。我应该为每个 repo 生成一个新的 base64 编码密钥吗?
示例代码不是很清楚 key
实际上是什么以及从哪里得到它。您需要从 /repos/{owner}/{repo}/actions/secrets/public-key
端点获得的“存储库 public 密钥”。
将存储库 public 密钥与新密钥中的值一起使用:
const key = "base64-encoded-public-key"; // this is the repository public key you need to fetch from GitHub
const value = "plain-text-secret"; // the secret value
然后你可以create or update你的密钥:
const res = await octokit.actions.createOrUpdateRepoSecret({
owner: "GITHUBUSER",
repo: "GITHUB_REPO",
secret_name: "KEY_NAME",
encrypted_value: encrypted,
});
这是我使用的代码。
const crypto = require('crypto');
const sodium = require('tweetsodium');
const { Octokit } = require("@octokit/core");
// Create a personal access token at https://github.com/settings/tokens/new?scopes=repo
const octokit = new Octokit({ auth: process.env.GH_PERSONAL_ACCESS_TOKEN });
module.exports = async () => {
const encryptionKey = crypto.randomBytes(16).toString('hex');
const publicKeyResponse = await octokit.request('GET /repos/<USERNAME>/<REPO>/actions/secrets/public-key');
const publicKey = publicKeyResponse.data.key;
const publicKeyId = publicKeyResponse.data.key_id;
// Convert the message and key to Uint8Array's (Buffer implements that interface)
const messageBytes = Buffer.from(encryptionKey);
const keyBytes = Buffer.from(publicKey, 'base64');
// Encrypt using LibSodium.
const encryptedBytes = sodium.seal(messageBytes, keyBytes);
// Base64 the encrypted secret
const encryptedEncryptionKey = Buffer.from(encryptedBytes).toString('base64');
await octokit.request('PUT /repos/<USERNAME>/<REPO>/actions/secrets/ENCRYPTION_KEY', {
owner: '<USERNAME>',
repo: '<REPO>',
secret_name: 'ENCRYPTION_KEY',
key_id: publicKeyId,
encrypted_value: encryptedEncryptionKey,
});
return encryptionKey;
};
我想通过 GitHub REST API 设置存储库机密。我使用 docs:
中的示例const sodium = require('tweetsodium');
const key = "base64-encoded-public-key";
const value = "plain-text-secret";
// Convert the message and key to Uint8Array's (Buffer implements that interface)
const messageBytes = Buffer.from(value);
const keyBytes = Buffer.from(key, 'base64');
// Encrypt using LibSodium.
const encryptedBytes = sodium.seal(messageBytes, keyBytes);
// Base64 the encrypted secret
const encrypted = Buffer.from(encryptedBytes).toString('base64');
console.log(encrypted);
我收到此错误:
(node:6008) UnhandledPromiseRejectionWarning: Error: bad public key size
at checkBoxLengths (C:\Users\User\probot\node_modules\tweetnacl\nacl-fast.js:2158:54)
at Function.nacl.box.before (C:\Users\User\probot\node_modules\tweetnacl\nacl-fast.js:2231:3)
at Object.nacl.box (C:\Users\User\probot\node_modules\tweetnacl\nacl-fast.js:2225:20)
at Object.tweetSodium.seal (C:\Users\User\probot\node_modules\tweetsodium\dist\index.umd.js:53:33)
at createSecret (C:\Users\User\probot\src\service\secret.js:55:33)
at Object.<anonymous> (C:\Users\User\probot\src\service\secret.js:73:1)
at Module._compile (internal/modules/cjs/loader.js:1138:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
at Module.load (internal/modules/cjs/loader.js:986:32)
at Function.Module._load (internal/modules/cjs/loader.js:879:14)
(node:6008) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:6008) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
问题:我如何正确地加密和解密秘密以便我可以在我的 API 中使用它?
解决方案:@Topaco提到您需要使用base64编码的密钥,例如2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvvcCU=
。这解决了上述错误。
编辑
我将在不同的存储库中使用不同的秘密。我应该为每个 repo 生成一个新的 base64 编码密钥吗?
示例代码不是很清楚 key
实际上是什么以及从哪里得到它。您需要从 /repos/{owner}/{repo}/actions/secrets/public-key
端点获得的“存储库 public 密钥”。
将存储库 public 密钥与新密钥中的值一起使用:
const key = "base64-encoded-public-key"; // this is the repository public key you need to fetch from GitHub
const value = "plain-text-secret"; // the secret value
然后你可以create or update你的密钥:
const res = await octokit.actions.createOrUpdateRepoSecret({
owner: "GITHUBUSER",
repo: "GITHUB_REPO",
secret_name: "KEY_NAME",
encrypted_value: encrypted,
});
这是我使用的代码。
const crypto = require('crypto');
const sodium = require('tweetsodium');
const { Octokit } = require("@octokit/core");
// Create a personal access token at https://github.com/settings/tokens/new?scopes=repo
const octokit = new Octokit({ auth: process.env.GH_PERSONAL_ACCESS_TOKEN });
module.exports = async () => {
const encryptionKey = crypto.randomBytes(16).toString('hex');
const publicKeyResponse = await octokit.request('GET /repos/<USERNAME>/<REPO>/actions/secrets/public-key');
const publicKey = publicKeyResponse.data.key;
const publicKeyId = publicKeyResponse.data.key_id;
// Convert the message and key to Uint8Array's (Buffer implements that interface)
const messageBytes = Buffer.from(encryptionKey);
const keyBytes = Buffer.from(publicKey, 'base64');
// Encrypt using LibSodium.
const encryptedBytes = sodium.seal(messageBytes, keyBytes);
// Base64 the encrypted secret
const encryptedEncryptionKey = Buffer.from(encryptedBytes).toString('base64');
await octokit.request('PUT /repos/<USERNAME>/<REPO>/actions/secrets/ENCRYPTION_KEY', {
owner: '<USERNAME>',
repo: '<REPO>',
secret_name: 'ENCRYPTION_KEY',
key_id: publicKeyId,
encrypted_value: encryptedEncryptionKey,
});
return encryptionKey;
};