poly-crypto/poly-crypto

NodeJS和PHP 7.1+之间互操作的高级加密函数

2.0.6 2022-04-21 22:40 UTC

This package is auto-updated.

Last update: 2024-09-24 15:52:24 UTC


README

Polyglot Cryptography。NodeJS和PHP 7.1+之间互操作的高级加密函数。

NPM Link Packagist Link Language Build Status Code Coverage Gzipped Size Dependency details Tree shakeable ISC License

项目目标

  1. NodeJS和PHP 7.1+上工作完全相同的API
  2. 适用于无服务器函数的Node包,无需外部C绑定
  3. 使用密钥或使用密码和盐进行双向对称加密
  4. 密码散列
  5. 支持ESM和tree shaking;支持CommonJS;TypeScript

安装

# NodeJS
npm install poly-crypto

# PHP
composer require poly-crypto/poly-crypto

速查表

目录

  1. 技术选择
    1. AES-255 GCM
    2. Bcrypt
    3. 随机性
  2. 用例
  3. 误用
  4. AES加密
    1. 使用密钥加密和解密
    2. 使用密码加密和解密
  5. 密码散列
  6. 摘要函数
  7. 随机函数
  8. 性能
  9. 命令行工具
  10. 浏览器使用
  11. JavaScript直接导入
  12. 单元测试
  13. 开源ISC许可证
  14. 变更日志

技术选择

AES-256 GCM

截至2022年12月,AES-256加密与GCM块模式是一种在PHP和NodeJS中无需任何扩展即可使用的知名且安全的方法。使用正确的参数和选项,这两种语言可以使用PHP的openssl_*函数和npm的node-forge相互解密加密字符串。

Bcrypt

截至2022年12月,Bcrypt密码散列是知名且安全的。这两种语言可以相互散列和验证对方的散列:npm的bcrypt-js和PHP的password_hash函数。

随机性

加密随机性很复杂。这两种语言可以提供安全的随机性:PHP的random_bytes()和Node的crypto.randomBytes()函数。

用例

poly-crypto的基本用例

误用

  1. 文件加密。 poly-crypto模块不适用于加密整个文件。您会希望使用一个设计用于快速加密大量数据的基于C的库。例如,考虑以下
    1. poly-crypto对大文件不快。
    2. AES-256 GCM加密可以在支持线程的语言中并行化,以实现更快的处理
  2. 流数据。 PolyAES未设计用于加密流数据。
  3. 安全密钥存储。 如果您以纯文本形式存储加密密钥或用户密码,则加密不会提供保护。您会希望将密钥存储在安全的参数存储中。
  4. 密码摘要。 不要使用md5或任何sha摘要来散列密码,即使您使用了盐。PolyBcrypt是唯一为散列密码设计的poly-crypto模块。

AES加密

使用密钥加密和解密

注意:密钥应是一个64字符的十六进制编码字符串,存储在安全的参数存储中。要生成一个加密安全的随机密钥,请使用PolyAES.generateKey(64)

NodeJS

import { PolyAES } from 'poly-crypto';

const hexKey = '64-char hex encoded string from secure param store';
const encrypted = PolyAES.withKey(hexKey).encrypt(data);
const decrypted = PolyAES.withKey(hexKey).decrypt(encrypted);

PHP

<?php

require_once('vendor/autoload.php');
use PolyCrypto\PolyAES;

$hexKey = '64-char hex encoded string from secure param store';
$encrypted = PolyAES::withKey($hexKey)->encrypt($data);
$decrypted = PolyAES::withKey($hexKey)->decrypt($encrypted);

注意:您可以重用“cipher”对象。例如

NodeJS

import { PolyAES } from 'poly-crypto';

const hexKey = '64-char hex encoded string from secure param store';
const cipher = PolyAES.withKey(hexKey);
const encrypted = cipher.encrypt(data);
const decrypted = cipher.decrypt(encrypted);

PHP

<?php

require_once('vendor/autoload.php');
use PolyCrypto\PolyAES;

$hexKey = '64-char hex encoded string from secure param store';
$cipher = PolyAES::withKey($hexKey);
$encrypted = $cipher->encrypt($data);
$decrypted = $cipher->decrypt($encrypted);

使用密码加密和解密

NodeJS

import { PolyAES } from 'poly-crypto';

const password = 'String from user';
const salt = 'String from secure param store';
const encrypted = PolyAES.withPassword(password, salt).encrypt(data);
const decrypted = PolyAES.withPassword(password, salt).decrypt(encrypted);

PHP

<?php

require_once('vendor/autoload.php');
use PolyCrypto\PolyAES;

$password = 'String from user';
$salt = 'String from secure param store';
$encrypted = PolyAES::withPassword($password, $salt)->encrypt($data);
$decrypted = PolyAES::withPassword($password, $salt)->decrypt($encrypted);

注意:您可以重用“cipher”作为对象。

密码散列

Bcrypt散列设计用于存储最大长度为72字节的用户密码。如果传递更长的字符串,将抛出异常。请记住,Unicode字符需要多个字节。

Bcrypt方便地将盐与密码一起存储。这确保了相同的密码将获得不同的散列值。因此,您不能比较两个散列值,必须使用PolyBcrypt.verify()函数来查看给定的密码是否与您记录的散列值匹配。

NodeJS

import { PolyBcrypt } from 'poly-crypto';

const password = 'Password from a user';
const hash = PolyBcrypt.hash(password);
const isCorrect = PolyBcrypt.verify(password, hash);

PHP

<?php

require_once('vendor/autoload.php');
use PolyCrypto\PolyBcrypt;

$password = 'Password from a user';
$hash = PolyBcrypt::hash($password);
$isCorrect = PolyBcrypt::verify($password, $hash);

摘要函数

标准单向散列函数。

NodeJS

import { PolyDigest } from 'poly-crypto';

PolyDigest.sha512(data);
PolyDigest.sha256(data);
PolyDigest.sha1(data);
PolyDigest.md5(data);

PHP

<?php

require_once('vendor/autoload.php');
use PolyCrypto\PolyDigest;

PolyDigest::sha512($data);
PolyDigest::sha256($data);
PolyDigest::sha1($data);
PolyDigest::md5($data);

随机函数

简单的函数用于同步生成随机值。

NodeJS

import { PolyRand } from 'poly-crypto';

// generate a string containing numbers and letters minus vowels
// suitable for resources such as URLs with random strings
PolyRand.slug(length);

// generate a string containing hexadecimal characters
PolyRand.hex(length);

// generate a string containing numbers and lowercase letters
// that are unambiguous when written down
PolyRand.fax(length);

// generate a string containing lowercase letters minus vowels
const symbolList = 'bcdfghjklmnpqrstvwxyz'.split('');
PolyRand.string(length, symbolList);

// generate random bytes in binary form
PolyRand.bytes(length);

// generate a uuid v4
PolyRand.uuidv4();

PHP

<?php

require_once('vendor/autoload.php');
use PolyCrypto\PolyRand;

// generate a string containing numbers and letters minus vowels
// suitable for resources such as URLs with random strings
PolyRand::slug($length);

// generate a string containing hexadecimal characters
PolyRand::hex($length);

// generate a string containing numbers and lowercase letters
// that are unambiguous when written down
PolyRand::fax($length);

// generate a string containing lowercase letters minus vowels
$symbolList = explode('', 'bcdfghjklmnpqrstvwxyz');
PolyRand::string($length, $symbolList);

// generate random bytes in binary form
PolyRand::bytes($length);

// generate a uuid v4
PolyRand::uuidv4();

命令行工具

如果已安装Node JS,则可以使用poly-crypto函数从命令行进行使用。

全局安装poly-crypto

您将获得以下作为符号链接的命令

# Global install command and arguments        # JavaScript equivalent
# ------------------------------------------- # ---------------------
npx key-encrypt $hexKey $plaintext            # PolyAES.withKey(hexKey).encrypt(plaintext)
npx key-decrypt $hexKey $ciphertext           # PolyAES.withKey(hexKey).decript(ciphertext)
npx pass-encrypt $password $salt $plaintext   # PolyAES.withPassword(password, salt).encrypt(plaintext)
npx pass-decrypt $password $salt $ciphertext  # PolyAES.withPassword(password, salt).decrypt(plaintext)
npx bcrypt-hash $password                     # PolyBcrypt.hash(password)
npx bcrypt-verify $password $againstHash      # PolyBcrypt.verify(password, againstHash)
npx poly-digest $algo $string                 # PolyDigest[algo](data) where algo is one of: sha1, sha256, sha512, md5
npx poly-rand $type $length                   # PolyRand[type](length) where type is one of: slug, hex, fax, bytes, uuidv4
npx poly-rand-string $length $symbolString    # PolyRand.string(length, symbolList) where symbolList is a string containing allowed characters

本地安装poly-crypto

在上述每个命令前加npm exec

浏览器使用

所有poly-crypto模块确实在浏览器中运行。只有在少数情况下,在浏览器中加密才是好主意。如果您有使用poly-crypto在浏览器中的合理理由,请参阅以下部分,了解直接导入Poly*模块的说明。

JavaScript直接导入

如果您正在使用ESM或类似viteesbuild的打包器,您可以通过使用导入语句来受益于树摇。

import { PolyBcrypt } from 'poly-crypto';

单元测试

# test both languages
npm run test:all

# PHP
./vendor/bin/kahlan --spec=php/tests

# NodeJS
npm test

贡献

欢迎贡献!请参阅CONTRIBUTING.md

许可

开源软件,遵循ISC许可证