bedrock-protocol/src/auth/tests/encrypt.js
extremeheat 51c1942153 move files
2021-02-03 13:17:13 -05:00

232 lines
No EOL
8 KiB
JavaScript

const crypto = require('crypto')
const JWT = require('jsonwebtoken')
const constants = require('./constants')
const { Ber } = require('asn1')
const ec_pem = require('ec-pem');
// function Encrypt(client, options) {
// this.startClientboundEncryption = (pubKeyBuf) => {
// }
// client.on('start_encrypt', this.startClientboundEncryption)
// }
// module.exports = Encrypt
// Server -> Client : sent right after the client sends us a LOGIN_PACKET so
// we can start the encryption process
// @param {key} - The key from the client Login Packet final JWT chain
function startClientboundEncryption(pubKeyBuf) {
// create our ecdh keypair
const type = 'secp256k1'
const alice = crypto.createECDH(type)
const aliceKey = alice.generateKeys()
const alicePublicKey = aliceKey.toString('base64')
const alicePrivateKey = mcPubKeyToPem(alice.getPrivateKey('base64'))
// get our secret key hex encoded
// const aliceSecret = alice.computeSecret(pubKeyBuf, null, 'hex')
// (yawkat:)
// From the public key of the remote and the private key of the local,
// a shared secret is generated using ECDH. The secret key bytes are
// then computed as sha256(server_token + shared_secret). These secret
// key bytes are 32 bytes long.
const salt = Buffer.from('', 'utf-8')
let secret = crypto.createHash('sha256').update(Buffer.concat([salt, pubKeyBuf])).digest()
console.log('alice', alicePrivateKey)
const pem = mcPubKeyToPem(alice.getPrivateKey().toString('base64'))
console.log('pem', pem)
const token = JWT.sign({
salt,
signedToken: alicePublicKey
}, pem, { algorithm: 'ES384' })
console.log('Token', token)
// get our Secret Bytes from the secret key
// alice.setPrivateKey(
// crypto.createHash('sha256').update('alice', 'utf8').digest()
// )
// using (var sha = SHA256.Create())
// {
// secret = sha.ComputeHash(secretPrepend.Concat(agreement.CalculateAgreement(remotePublicKey).ToByteArrayUnsigned()).ToArray());
// }
const bob = crypto.createECDH('secp256k1');
// URI x5u = URI.create(Base64.getEncoder().encodeToString(serverKeyPair.getPublic().getEncoded()));
// JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().claim("salt", Base64.getEncoder().encodeToString(token)).build();
// SignedJWT jwt = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.ES384).x509CertURL(x5u).build(), claimsSet);
// signJwt(jwt, (ECPrivateKey) serverKeyPair.getPrivate());
// return jwt;
}
function testECDH() {
const crypto = require('crypto')
const alice = crypto.createECDH('secp256k1')
const bob = crypto.createECDH('secp256k1')
// Note: This is a shortcut way to specify one of Alice's previous private
// keys. It would be unwise to use such a predictable private key in a real
// application.
alice.setPrivateKey(
crypto.createHash('sha256').update('alice', 'utf8').digest()
);
// Bob uses a newly generated cryptographically strong
// pseudorandom key pair bob.generateKeys();
const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex')
const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex')
// alice_secret and bob_secret should be the same shared secret value
console.log(alice_secret === bob_secret)
}
function testECDH2() {
const type = 'secp256k1'
const alice = crypto.createECDH(type);
const aliceKey = alice.generateKeys();
// Generate Bob's keys...
const bob = crypto.createECDH(type);
const bobKey = bob.generateKeys();
console.log("\nAlice private key:\t", alice.getPrivateKey().toString('hex'));
console.log("Alice public key:\t", aliceKey.toString('hex'))
console.log("\nBob private key:\t", bob.getPrivateKey().toString('hex'));
console.log("Bob public key:\t", bobKey.toString('hex'));
// Exchange and generate the secret...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);
console.log("\nAlice shared key:\t", aliceSecret.toString('hex'))
console.log("Bob shared key:\t\t", bobSecret.toString('hex'));
//wow it actually works?!
}
function mcPubKeyToPem(mcPubKeyBuffer) {
console.log(mcPubKeyBuffer)
if (mcPubKeyBuffer[0] == '-') return mcPubKeyBuffer
let pem = '-----BEGIN PUBLIC KEY-----\n'
let base64PubKey = mcPubKeyBuffer.toString('base64')
const maxLineLength = 65
while (base64PubKey.length > 0) {
pem += base64PubKey.substring(0, maxLineLength) + '\n'
base64PubKey = base64PubKey.substring(maxLineLength)
}
pem += '-----END PUBLIC KEY-----\n'
return pem
}
function readX509PublicKey(key) {
var reader = new Ber.Reader(Buffer.from(key, "base64"));
reader.readSequence();
reader.readSequence();
reader.readOID(); // Hey, I'm an elliptic curve
reader.readOID(); // This contains the curve type, could be useful
return Buffer.from(reader.readString(Ber.BitString, true)).slice(1);
}
function testMC() {
// const pubKeyBuf = Buffer.from(constants.PUBLIC_KEY, 'base64')
// const pem = mcPubKeyToPem(pubKeyBuf)
// console.log(mcPubKeyToPem(pubKeyBuf))
// const publicKey = crypto.createPublicKey({ key: pem, format: 'der' })
const pubKeyBuf = readX509PublicKey(constants.PUBLIC_KEY)
// console.log('Mojang pub key', pubKeyBuf.toString('hex'), publicKey)
startClientboundEncryption(pubKeyBuf)
}
function testMC2() {
// const mojangPubKeyBuf = Buffer.from('MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuKdm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V', 'base64')
// const pem = mcPubKeyToPem(mojangPubKeyBuf)
// const publicKey = crypto.createPublicKey({ key: pem })
const publicKey = readX509PublicKey(constants.PUBLIC_KEY)
const curve = 'secp384r1'
const alice = crypto.createECDH(curve)
// const keys = crypto.generateKeyPair('ec',)
// const bob = crypto.generateKeyPairSync('ec', {
// namedCurve: type
// })
// alice.setPrivateKey(bob.privateKey.export({ type: 'pkcs8', format: 'pem' }))
// alice.setPublicKey(bob.publicKey.export({ type: 'spki', format: 'pem' }))
// console.log(bob)
const aliceKey = alice.generateKeys()
const alicePEM = ec_pem(alice, curve)
const alicePEMPrivate = alicePEM.encodePrivateKey()
const alicePEMPublic = alicePEM.encodePublicKey()
// const alicePublicKey = aliceKey.toString('base64')
// const alicePrivateKey = alice.getPrivateKey().toString('base64')
const aliceSecret = alice.computeSecret(publicKey, null, 'hex')
console.log('Alice private key PEM', alicePEMPrivate)
console.log('Alice public key PEM', alicePEMPublic)
console.log('Alice public key', alice.getPublicKey('base64'))
console.log('Alice secret key', aliceSecret)
var sign = crypto.createSign('RSA-SHA256')
sign.write('something')
sign.end()
// // const pem2 =
// // `-----BEGIN PRIVATE KEY-----
// // ${alice.getPrivateKey('base64')}
// // -----END PRIVATE KEY-----`
// console.log('PEM', bob.privateKey)
const sig = sign.sign(alicePEMPrivate, 'hex')
console.log('Signature', sig)
const token = JWT.sign({
salt: 'HELLO',
signedToken: alice.getPublicKey('base64')
}, alicePEMPrivate, { algorithm: 'ES384' })
console.log('Token', token)
const verified = JWT.verify(token, alicePEMPublic, { algorithms: 'ES384' })
console.log('Verified!', verified)
}
function testMC3() {
var Ber = require('asn1').Ber;
var reader = new Ber.Reader(new Buffer(constants.PUBLIC_KEY, "base64"));
reader.readSequence();
reader.readSequence();
reader.readOID(); // Hey, I'm an elliptic curve
reader.readOID(); // This contains the curve type, could be useful
var pubKey = reader.readString(Ber.BitString, true).slice(1);
var server = crypto.createECDH('secp384r1');
server.generateKeys();
console.log(server.computeSecret(pubKey));
}
// testECDH2()
testMC2()