公钥私钥加密和SHA256

公钥和私钥

公钥(Public Key)与私钥(Private Key)是通过一种算法得到的一个密钥对(即一个公钥和一个私钥),公钥是密钥对中公开的部分,私钥则是非公开的部分。公钥通常用于加密会话密钥、验证数字签名,或加密可以用相应的私钥解密的数据。

公钥和私钥是成对出现的,我们会保留有自己的私钥,同时公开自己的公钥。一个很典型的例子是GitHub的使用。我们通常不会使用账号密码来管理自己的项目,而是通过将自己的公钥上传到GitHub的里,而自己的电脑里则保留有相对应的私钥,从而达到免密码提交代码。

当然私钥和公钥对是唯一的,而你也可以随时重新生成自己的公钥和私钥密码对,但当你从新生成密钥对并覆盖了就有的密钥时,你之前的公钥就作废了。

简单来说就是:
公钥加密,私钥解密,
私钥签名,公钥验证。

SHA256

SHA256是一种安全哈希算法。

简单介绍一下就是,对于任何一段信息,通过SHA256变换之后,都会是一个固定的 256 位由 0 和 1 组成的输出。同时,对于相同的信息,输出一样,而对于不一样的信息,输出则有很大的区别,即使只有一丁点的输入不一样,输出也会有非常大的不一样。

同时,虽然信息输入是无限的,而 SHA256 的输出是有限的(256位),但是根据我们目前的条件和计算能力水平来说,几乎找不到有两个不同的输入,可以得到相同的输出。也即我们可以认为是不可能的。

代码

接下来我们,我们使用 Js 的 ursa 库来生成公钥和私钥

generatePrivateAndPubKey.js

const ursa = require("ursa");
const fs = require("fs");
const path = require("path");

const MODULUSBIT = 1024;

class Key {
  static generateKeys(pathName) {
    const key = ursa.generatePrivateKey(MODULUSBIT, 65537);

    const privatePem = key.toPrivatePem("utf8");
    const privateKey = ursa.createPrivateKey(privatePem); // generate private key
    const privateFileName = path.join(pathName, "private.pem");

    const publicPem = key.toPublicPem("utf8");
    const publicKey = ursa.createPublicKey(publicPem); // generate public key
    const publicFileName = path.join(pathName, "public.pub");

    if (!fs.existsSync(pathName)) {
      fs.mkdirSync(pathName);
    }

    fs.writeFileSync(privateFileName, privatePem, "utf8");
    fs.writeFileSync(publicFileName, publicPem, "utf8");

    return {
      privateKey: privateKey,
      publicKey: publicKey
    };
  }

  static signMessage(privateKey, message) {}
}

module.exports = exports = Key;

test.js

const Key = require("./generatePrivateAndPubKey.js");
const SHA256 = require("crypto-js/sha256");
const ursa = require("ursa");

const fs = require("fs");
const encoding = "base64";
const algorigthm = "sha256";
const message = "Hello world";

let buffer = new Buffer(message, encoding);

// use Bob's private key to signed message
const BobKeys = Key.generateKeys("Bob");
const signedMessage = BobKeys.privateKey.sign(
  algorigthm,
  buffer,
  encoding,
  encoding
);

// use Bob's public to verify the message
const isValid = BobKeys.publicKey.verify(
  algorigthm,
  buffer,
  signedMessage,
  encoding
);

// use Bob's public key to encrypt message
const encrypted = BobKeys.publicKey.encrypt(message, encoding, "base64");
// use Bob's private key to dencrypt message
const decrypted = BobKeys.privateKey.decrypt(encrypted, "base64", encoding);

console.log("Original Message:", message, "\n");
console.log("Singed Message:", signedMessage, "\n");
console.log("isValid", isValid, "\n");
console.log("Encrypted message:", encrypted, "\n");
console.log("Decrypted message:", decrypted, "\n");

输出

Original Message: Hello world

Singed Message: ARSvIgmY7iIznhuk70stOIj8bBzj4A58wlHKKUPerU1WRob+Mk3U7p5hEhX4+lyLi/F6m3O4dfJ4dESQ2aO+deocjQd4F4zv2s2RC7AhST0nIT0F4iJYAct73R1Azum8MQK+7tesKLUYPLTfjQcvaNDhG+yDl9KfMrGO/Jgtoms=

isValid true

Encrypted message: 5ItG99B3H0h4lbpDDLwD8rza1nPWleWlvOok475lFLxYaI5AvdDetGZq+Cw5K/kcOb6qnpYcoNij1OCgiuSAad352vc596jEFExRZlhsTCqXTtqXblfEPOn4PUtrzrS/jn2FEUke3icF4fqtvVKFYeYpTl1rfrANhe3NrY9F5ik=

Decrypted message: HelloworlQ==

接下来,让我们来测试一下 SHA256

let sha256Message = SHA256("1111").toString();
console.log("1111 After SHA256:", sha256Message, "\n");

sha256Message = SHA256("1112").toString();
console.log("1112 After SHA256:", sha256Message, "\n");

sha256Message = SHA256("111111111111111111").toString();
console.log("111111111111111111 After SHA256:", sha256Message, "\n");

sha256Message = SHA256("111211111111111111").toString();
console.log("111211111111111111 After SHA256:", sha256Message, "\n");

/*
Output:

1111 After SHA256: 0ffe1abd1a08215353c233d6e009613e95eec4253832a761af28ff37ac5a150c

1112 After SHA256: fe91a760983d401d9b679fb092b689488d1f46d92f3af5e9e93363326f3e8aa4

111111111111111111 After SHA256: 26980a9bf7dba794bd14eae90dbda34109d37f66950c16cce7b87dffd4535b40

111211111111111111 After SHA256: 308c3ae83c039dee107a232c4ccb4ee4a65ef3fb1e41357a6b9b240e88b09c0e
*/

Base64 和 Base58

比特币里用的编码方式是 Base58, 但是因为我们使用的测试库 ursa并不支持 Base58, 因此我们只能使用Base64。Base64 和 Base64 并没有什么太大的区别,在这里并不会影响我们对加解密,数字签名的理解。

为什么比特币要使用Base58呢?这里引用一下比特币源码里的注释。

//
// Why base-58 instead of standard base-64 encoding?
// - Don’t want 0OIl characters that look the same in some fonts and
// could be used to create visually identical looking account numbers.
// - A string with non-alphanumeric characters is not as easily accepted as an account number.
// - E-mail usually won’t line-break if there’s no punctuation to break at.
// - Doubleclicking selects the whole number as one word if it’s all alphanumeric.
//

简单来说就是去掉 O, I, L 这些不好区分的字符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值