RSA encrypt/decrypt use asmcrypto as well
TODO: RSA key generation, removing jsbn from dsa, elgamal, mpi, etc.
This commit is contained in:
parent
aee8974ef5
commit
b126fd5be7
|
@ -18,23 +18,28 @@
|
||||||
// The GPG4Browsers crypto interface
|
// The GPG4Browsers crypto interface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @requires crypto/cipher
|
* @requires asmcrypto.js
|
||||||
* @requires crypto/public_key
|
* @requires crypto/public_key
|
||||||
|
* @requires crypto/cipher
|
||||||
* @requires crypto/random
|
* @requires crypto/random
|
||||||
* @requires type/ecdh_symkey
|
* @requires type/ecdh_symkey
|
||||||
* @requires type/kdf_params
|
* @requires type/kdf_params
|
||||||
* @requires type/mpi
|
* @requires type/mpi
|
||||||
* @requires type/oid
|
* @requires type/oid
|
||||||
|
* @requires util
|
||||||
* @module crypto/crypto
|
* @module crypto/crypto
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import random from './random.js';
|
import { RSA_RAW, BigNumber, Modulus } from 'asmcrypto.js';
|
||||||
import cipher from './cipher';
|
import BigInteger from './public_key/jsbn';
|
||||||
import publicKey from './public_key';
|
import publicKey from './public_key';
|
||||||
import type_ecdh_symkey from '../type/ecdh_symkey.js';
|
import cipher from './cipher';
|
||||||
import type_kdf_params from '../type/kdf_params.js';
|
import random from './random';
|
||||||
import type_mpi from '../type/mpi.js';
|
import type_ecdh_symkey from '../type/ecdh_symkey';
|
||||||
import type_oid from '../type/oid.js';
|
import type_kdf_params from '../type/kdf_params';
|
||||||
|
import type_mpi from '../type/mpi';
|
||||||
|
import type_oid from '../type/oid';
|
||||||
|
import util from '../util';
|
||||||
|
|
||||||
|
|
||||||
function constructParams(types, data) {
|
function constructParams(types, data) {
|
||||||
|
@ -63,11 +68,12 @@ export default {
|
||||||
switch (algo) {
|
switch (algo) {
|
||||||
case 'rsa_encrypt':
|
case 'rsa_encrypt':
|
||||||
case 'rsa_encrypt_sign': {
|
case 'rsa_encrypt_sign': {
|
||||||
const rsa = new publicKey.rsa();
|
const n = util.str2Uint8Array(publicParams[0].toBytes());
|
||||||
const n = publicParams[0].toBigInteger();
|
const e = util.str2Uint8Array(publicParams[1].toBytes());
|
||||||
const e = publicParams[1].toBigInteger();
|
m = data.write().slice(2); // FIXME
|
||||||
m = data.toBigInteger();
|
return constructParams(types, [
|
||||||
return constructParams(types, [rsa.encrypt(m, e, n)]);
|
new BigInteger(util.hexidump(RSA_RAW.encrypt(m, [n, e])), 16) // FIXME
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
case 'elgamal': {
|
case 'elgamal': {
|
||||||
const elgamal = new publicKey.elgamal();
|
const elgamal = new publicKey.elgamal();
|
||||||
|
@ -109,17 +115,23 @@ export default {
|
||||||
switch (algo) {
|
switch (algo) {
|
||||||
case 'rsa_encrypt_sign':
|
case 'rsa_encrypt_sign':
|
||||||
case 'rsa_encrypt': {
|
case 'rsa_encrypt': {
|
||||||
const rsa = new publicKey.rsa();
|
const c = util.str2Uint8Array(dataIntegers[0].toBytes());
|
||||||
// 0 and 1 are the public key.
|
const n = util.str2Uint8Array(keyIntegers[0].toBytes()); // pq
|
||||||
const n = keyIntegers[0].toBigInteger();
|
const e = util.str2Uint8Array(keyIntegers[1].toBytes());
|
||||||
const e = keyIntegers[1].toBigInteger();
|
const d = util.str2Uint8Array(keyIntegers[2].toBytes()); // de = 1 mod (p-1)(q-1)
|
||||||
// 2 to 5 are the private key.
|
const p = util.str2Uint8Array(keyIntegers[3].toBytes());
|
||||||
const d = keyIntegers[2].toBigInteger();
|
const q = util.str2Uint8Array(keyIntegers[4].toBytes());
|
||||||
p = keyIntegers[3].toBigInteger();
|
const u = util.str2Uint8Array(keyIntegers[5].toBytes()); // q^-1 mod p
|
||||||
const q = keyIntegers[4].toBigInteger();
|
const dd = BigNumber.fromArrayBuffer(d);
|
||||||
const u = keyIntegers[5].toBigInteger();
|
const dp = new Modulus(
|
||||||
const m = dataIntegers[0].toBigInteger();
|
BigNumber.fromArrayBuffer(p).subtract(BigNumber.ONE)
|
||||||
return rsa.decrypt(m, n, e, d, p, q, u);
|
).reduce(dd).toBytes(); // d mod (p-1)
|
||||||
|
const dq = new Modulus(
|
||||||
|
BigNumber.fromArrayBuffer(q).subtract(BigNumber.ONE)
|
||||||
|
).reduce(dd).toBytes(); // d mod (q-1)
|
||||||
|
return new BigInteger(
|
||||||
|
util.hexidump(RSA_RAW.decrypt(c, [n, e, d, q, p, dq, dp, u]).slice(1)), 16 // FIXME
|
||||||
|
);
|
||||||
}
|
}
|
||||||
case 'elgamal': {
|
case 'elgamal': {
|
||||||
const elgamal = new publicKey.elgamal();
|
const elgamal = new publicKey.elgamal();
|
||||||
|
|
|
@ -191,8 +191,8 @@ async function generate(curve) {
|
||||||
const keyPair = await curve.genKeyPair();
|
const keyPair = await curve.genKeyPair();
|
||||||
return {
|
return {
|
||||||
oid: curve.oid,
|
oid: curve.oid,
|
||||||
Q: new BigInteger(keyPair.getPublic()),
|
Q: new BigInteger(util.hexidump(keyPair.getPublic()), 16),
|
||||||
d: new BigInteger(keyPair.getPrivate()),
|
d: new BigInteger(util.hexidump(keyPair.getPrivate()), 16),
|
||||||
hash: curve.hash,
|
hash: curve.hash,
|
||||||
cipher: curve.cipher
|
cipher: curve.cipher
|
||||||
};
|
};
|
||||||
|
|
|
@ -86,7 +86,7 @@ async function encrypt(oid, cipher_algo, hash_algo, m, Q, fingerprint) {
|
||||||
const Z = kdf(hash_algo, S, cipher[cipher_algo].keySize, param);
|
const Z = kdf(hash_algo, S, cipher[cipher_algo].keySize, param);
|
||||||
const C = aes_kw.wrap(Z, m.toBytes());
|
const C = aes_kw.wrap(Z, m.toBytes());
|
||||||
return {
|
return {
|
||||||
V: new BigInteger(v.getPublic()),
|
V: new BigInteger(util.hexidump(v.getPublic()), 16),
|
||||||
C: C
|
C: C
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ async function decrypt(oid, cipher_algo, hash_algo, V, C, d, fingerprint) {
|
||||||
d = curve.keyFromPrivate(d.toByteArray());
|
d = curve.keyFromPrivate(d.toByteArray());
|
||||||
const S = d.derive(V);
|
const S = d.derive(V);
|
||||||
const Z = kdf(hash_algo, S, cipher[cipher_algo].keySize, param);
|
const Z = kdf(hash_algo, S, cipher[cipher_algo].keySize, param);
|
||||||
return new BigInteger(aes_kw.unwrap(Z, C));
|
return new BigInteger(util.hexidump(aes_kw.unwrap(Z, C)), 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -18,12 +18,14 @@
|
||||||
// Implementation of ECDSA following RFC6637 for Openpgpjs
|
// Implementation of ECDSA following RFC6637 for Openpgpjs
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @requires util
|
||||||
* @requires crypto/hash
|
* @requires crypto/hash
|
||||||
* @requires crypto/public_key/jsbn
|
* @requires crypto/public_key/jsbn
|
||||||
* @requires crypto/public_key/elliptic/curves
|
* @requires crypto/public_key/elliptic/curves
|
||||||
* @module crypto/public_key/elliptic/ecdsa
|
* @module crypto/public_key/elliptic/ecdsa
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import util from '../../../util';
|
||||||
import hash from '../../hash';
|
import hash from '../../hash';
|
||||||
import curves from './curves';
|
import curves from './curves';
|
||||||
import BigInteger from '../jsbn';
|
import BigInteger from '../jsbn';
|
||||||
|
@ -41,8 +43,8 @@ async function sign(oid, hash_algo, m, d) {
|
||||||
const key = curve.keyFromPrivate(d.toByteArray());
|
const key = curve.keyFromPrivate(d.toByteArray());
|
||||||
const signature = await key.sign(m, hash_algo);
|
const signature = await key.sign(m, hash_algo);
|
||||||
return {
|
return {
|
||||||
r: new BigInteger(signature.r.toArray()),
|
r: new BigInteger(util.hexidump(signature.r.toArray()), 16),
|
||||||
s: new BigInteger(signature.s.toArray())
|
s: new BigInteger(util.hexidump(signature.s.toArray()), 16)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,8 @@ async function nodeSign(curve, hash_algo, message, keyPair) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function nodeVerify(curve, hash_algo, { r, s }, message, publicKey) {
|
async function nodeVerify(curve, hash_algo, { r, s }, message, publicKey) {
|
||||||
const signature = ECDSASignature.encode({ r: new BigInteger(r), s: new BigInteger(s) }, 'der');
|
const signature = ECDSASignature.encode(
|
||||||
|
{ r: new BigInteger(util.hexidump(r), 16), s: new BigInteger(util.hexidump(s), 16) }, 'der');
|
||||||
const key = jwkToPem(
|
const key = jwkToPem(
|
||||||
{
|
{
|
||||||
"kty": "EC",
|
"kty": "EC",
|
||||||
|
|
|
@ -89,6 +89,8 @@ export default function RSA() {
|
||||||
}
|
}
|
||||||
t = t.multiply(p).add(xp);
|
t = t.multiply(p).add(xp);
|
||||||
|
|
||||||
|
// var t = RSA.decrypt(m, [n, e, d, q, p, dq, dp, u]).slice(1)
|
||||||
|
|
||||||
if (config.rsa_blinding) {
|
if (config.rsa_blinding) {
|
||||||
t = unblind(t, n);
|
t = unblind(t, n);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
* @requires crypto/public_key
|
* @requires crypto/public_key
|
||||||
* @requires crypto/pkcs1
|
* @requires crypto/pkcs1
|
||||||
* @requires util
|
* @requires util
|
||||||
* @module crypto/signature */
|
* @module crypto/signature
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { RSA_RAW } from 'asmcrypto.js';
|
||||||
import { RSA_RAW } from 'asmcrypto.js'
|
|
||||||
import publicKey from './public_key';
|
import publicKey from './public_key';
|
||||||
import pkcs1 from './pkcs1';
|
import pkcs1 from './pkcs1';
|
||||||
import util from '../util';
|
import util from '../util';
|
||||||
|
@ -119,6 +119,7 @@ export default {
|
||||||
'00'+pkcs1.emsa.encode(hash_algo, data, k) // FIXME
|
'00'+pkcs1.emsa.encode(hash_algo, data, k) // FIXME
|
||||||
);
|
);
|
||||||
return util.Uint8Array2MPI(RSA_RAW.sign(m, [n, e, d]));
|
return util.Uint8Array2MPI(RSA_RAW.sign(m, [n, e, d]));
|
||||||
|
}
|
||||||
case 17: {
|
case 17: {
|
||||||
// DSA (Digital Signature Algorithm) [FIPS186] [HAC]
|
// DSA (Digital Signature Algorithm) [FIPS186] [HAC]
|
||||||
const dsa = new publicKey.dsa();
|
const dsa = new publicKey.dsa();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user