公钥私钥加密和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 这些不好区分的字符。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SSH公钥私钥是一对密钥,它们被用于在SSH协议下进行身份验证和加密通信。这里提供一个简单的SSH公钥私钥换算器的Python代码示例,可以将一个格式正确的SSH私钥转换为公钥或者将公钥转换为私钥。 ```python import base64 import hashlib def generate_public_key(private_key): """ 从SSH私钥生成SSH公钥 """ key_type, _, private_key = private_key.split(' ', 2) private_key = base64.b64decode(private_key) if key_type == 'ssh-rsa': # RSA公钥格式: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... exponent_length = int.from_bytes(private_key[0:4], byteorder='big') exponent = int.from_bytes(private_key[4:4+exponent_length], byteorder='big') modulus_length = int.from_bytes(private_key[4+exponent_length:8+exponent_length], byteorder='big') modulus = int.from_bytes(private_key[8+exponent_length:8+exponent_length+modulus_length], byteorder='big') public_key = 'ssh-rsa ' + base64.b64encode( b'\x00\x00\x00\x07ssh-rsa' + exponent_length.to_bytes(4, byteorder='big') + exponent.to_bytes((exponent.bit_length() + 7) // 8, byteorder='big') + modulus_length.to_bytes(4, byteorder='big') + modulus.to_bytes((modulus.bit_length() + 7) // 8, byteorder='big') ).decode('ascii') return public_key elif key_type == 'ssh-ed25519': # Ed25519公钥格式: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMcDa... public_key = 'ssh-ed25519 ' + base64.b64encode(private_key[32:]).decode('ascii') return public_key else: raise ValueError('Unsupported key type') def generate_private_key(public_key, private_key=None): """ 从SSH公钥生成SSH私钥 """ key_type, _, public_key = public_key.split(' ', 2) public_key = base64.b64decode(public_key) if key_type == 'ssh-rsa': # RSA私钥格式: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... if private_key is None: raise ValueError('Private key is required for RSA key type') exponent_length = private_key.find(b'\x00\x00\x00\x07ssh-rsa') + 11 exponent_length = int.from_bytes(private_key[exponent_length:exponent_length+4], byteorder='big') exponent = int.from_bytes(private_key[exponent_length+4:exponent_length+4+exponent_length], byteorder='big') modulus_length = int.from_bytes(private_key[exponent_length+4+exponent_length:exponent_length+4+exponent_length+4], byteorder='big') modulus = int.from_bytes(private_key[exponent_length+4+exponent_length+4:exponent_length+4+exponent_length+4+modulus_length], byteorder='big') private_key = b''.join([ b'\x00\x00\x00\x07ssh-rsa', exponent_length.to_bytes(4, byteorder='big'), exponent.to_bytes((exponent.bit_length() + 7) // 8, byteorder='big'), modulus_length.to_bytes(4, byteorder='big'), modulus.to_bytes((modulus.bit_length() + 7) // 8, byteorder='big'), private_key[public_key.__len__():] ]) private_key = key_type.encode('ascii') + b' ' + base64.b64encode(private_key).replace(b'\n', b'') + b' ' return private_key elif key_type == 'ssh-ed25519': # Ed25519私钥格式: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMcDa... if private_key is None: # 使用公钥生成随机私钥 private_key = hashlib.sha256(public_key).digest() private_key = key_type.encode('ascii') + b' ' + base64.b64encode(private_key).replace(b'\n', b'') + b' ' return private_key else: raise ValueError('Unsupported key type') ``` 使用示例: ```python # 生成RSA密钥对 from cryptography.hazmat.primitives.asymmetric import rsa private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) public_key = private_key.public_key() ssh_private_key = generate_private_key('ssh-rsa ' + base64.b64encode(public_key.public_bytes(encoding=serialization.Encoding.DER, format=serialization.PublicFormat.PKCS1)).decode('ascii'), private_key=private_key.private_bytes(encoding=serialization.Encoding.DER, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption())) ssh_public_key = generate_public_key(ssh_private_key) # 生成Ed25519密钥对 from cryptography.hazmat.primitives.asymmetric import ed25519 private_key = ed25519.Ed25519PrivateKey.generate() public_key = private_key.public_key() ssh_private_key = generate_private_key('ssh-ed25519 ' + base64.b64encode(public_key.public_bytes(encoding=serialization.Encoding.Raw, format=serialization.PublicFormat.Raw)).decode('ascii')) ssh_public_key = generate_public_key(ssh_private_key) ``` 注意:这个示例代码仅适用于支持PKCS#1和PKCS#8格式的RSA和Ed25519密钥。如果要使用其他格式的密钥,代码需要进行相应的修改。此外,为了安全起见,不应该在生产环境中使用此代码,而应该使用已经被广泛测试和验证的SSH密钥生成库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值