PRESS.one 开发者社区

PRESS.one 开发者社区

  • 文档
  • 博客
  • 开发者论坛

›指南

指南

  • 简介
  • DApp 开发流程
  • 创建 DApp
  • 数字签名相关知识
  • PRS 协议

REST API 文档

  • 概述
  • API 鉴权
  • 用户授权
  • 获取数字签名
  • 签名文件相关
  • 合约相关
  • 钱包相关

Node.js SDK 文档

  • SDK 安装
  • 用户授权
  • 签名文件相关
  • 合约相关
  • 钱包相关

数字签名相关知识

数字签名

数字签名是一种将类似现实世界中物理签名、盖章,在计算机世界中进行实现的技术。是使用了公钥加密领域的技术实现,用于鉴别数字信息的方法。使用数字签名可以识别篡改和伪造,还可以防止否认,具有不可抵赖性。

签名以及验证过程过程:

  1. A 用单向散列函数(Keccak256)求出消息的散列值。
  2. A 用自己的私钥对散列值进行签名。(使用椭圆加密算法进行签名)。
  3. A 将消息和签名发送给 B。
  4. B 用 A 的公钥对收到的签名进行解密。
  5. B 将解密后得到的散列值,与 A 直接发送的消息的散列值进行对比验证。

以下是对文本进行签名的过程

// Node Example
const signText = (text, privateKey) => {
  // 1. 用单向散列函数 keccak256 求出消息的散列值
  const hash = keccak256(text)

  // 2.  用自己的私钥对散列值进行加密
  const key = ec.keyFromPrivate(privateKey, 'hex');
  const signature = key.sign(hash);
  const sigHex = signature.r.toString(16, 32) +
    signature.s.toString(16, 32) +
    signature.recoveryParam.toString();

  return {
    hash,
    signature: sigHex
  };
};

在 nodejs SDK 中已经封装好了相关函数,加解密部分的实现可以参考prs-utility项目。

Keccak256

单向散列函数,是一种将长消息转换为短散列值的技术,用于确保消息完整性。

Keccak 是一种符合 SHA-3 标准的单向散列函数,可以生成任意长度的散列值。PRS 项目使用的是 Keccak-256 SHA3 算法,在 JavaScript 中使用的开源库是 js-sha3。

// Node Example
const jsSha3 = require('js-sha3');

let keccak256 = (message) => {
    return jsSha3.keccak256(message);
};

椭圆曲线密码

椭圆曲线密码是一种利用椭圆曲线数学来实现的密码技术的统称,是一种建立公钥密码的算法。

Secp256k1 是比特币使用的 ECDSA (椭圆曲线数字签名算法)曲线的参数,并且在高效密码学标准 (Certicom Research) 中进行了定义. PRS 项目也使用该算法来进行数字签名,在 JavaScript 中使用的开源库是 elliptic。

更多内容可参考: 公开密钥加密 椭圆曲线密码学 。

密钥对

在数字签名中,签名的生成和验证使用不同的密钥。生成签名使用的密钥被称为私钥,验证签名使用的密钥被称为公钥,任何人都能够使用公钥验证签名。

创建密钥对过程:

  1. 用随机数生成密钥,因为密钥需要具有不易被他人推测的性质。
  2. 通过椭圆曲线签名算法,推导出公钥。
  3. 从公钥经过 Keccak 单向散列函数推导出地址。
// Node Example
const createKeyPair = (options = { dump: true }) => {
  // 1. 用随机数生成密钥,因为密钥需要具有不易被他人推测的性质。
  let privateKey;
  do {
    privateKey = randomBytes(32);
  } while (!secp256k1.privateKeyVerify(privateKey));

  // 2. 通过椭圆曲线签名算法,推导出公钥。
  const publicKey = secp256k1.publicKeyCreate(privateKey);
  const convertKey = secp256k1.publicKeyConvert(publicKey, false).slice(1);

  // 3. 从公钥经过 Keccak 单向散列函数推导出地址。
  const publicAdd = ethUtil.pubToAddress(convertKey);

  return {
    privateKey: dumpBuf(privateKey, options),
    publicKey: dumpBuf(publicKey, options),
    address: dumpBuf(publicAdd, options)
  };
};
// dumpBuf 为工具函数,默认生成的所有 key 均为 Buffer,可根据需要 dump 成为 hex 字符串

在 PRS 中,用户注册以及用户授权都会生成新的密钥对。根据数字签名的特性,address 将作为用户在 PRS 系统中的唯一 ID,privateKey 用于签名操作,系统可以通过公开的 publishKey 来验证用户的权限。

Keystore

Keystore文件是以太坊钱包存储私钥的一种文件格式(JSON),它使用用户自定义密码加密,以起到一定程度上的保护作用,而保护的程度取决于用户加密该钱包的密码强度。

PRESS.one 使用的 keystore 格式是 eth 标准格式, 在 JavaScript 中使用的是开源库是 keythereum。

具体格式如:

{"address":"c2d7cf95645d33006175b78989035c7c9061d3f9",
  "crypto":{
    "cipher":"aes-128-ctr",
    "ciphertext":"0f6d343b2a34fe571639235fc16250823c6fe3bc30525d98c41dfdf21a97aedb",
    "cipherparams":{
      "iv":"cabce7fb34e4881870a2419b93f6c796"
    },
    "kdf":"scrypt",
    "kdfparams"{
      "dklen":32,
      "n":262144,
      "p":1,
      "r":8,
      "salt":"1af9c4a44cf45fe6fb03dcc126fa56cb0f9e81463683dd6493fb4dc76edddd51"
    },
    "mac":"5cf4012fffd1fbe41b122386122350c3825a709619224961a16e908c2a366aa6"
  },
  "id":"eddd71dd-7ad6-4cd3-bc1a-11022f7db76c",
  "version":3
}

获取私钥

通过 Keystore 文件加上密码,即可解密出用户的私钥,拿到私钥即可进行数字签名。

// Node Example
const recoverPrivateKey = (keystore, password) => {
  const privateKey = keythereum.recover(password, JSON.parse(keystore));
  return bufToHex(privateKey);
}
← 创建 DAppPRS 协议 →
  • 数字签名
  • Keccak256
  • 椭圆曲线密码
  • 密钥对
  • Keystore
文档
介绍基础知识创建 DApp创建合约
社区
TwitterMedium微信公众号开发者论坛
更多
官方博客GitHub
Copyright © 2023 PRESSone