gexiaowei
12/9/2016 - 8:33 AM

encrypto

encrypto

function rsaPublicKeyPem(modulus_b64, exponent_b64) {

    function prepadSigned(hexStr) {
        let msb = hexStr[0];
        if (
            (msb >= '8' && msb <= '9') ||
            (msb >= 'a' && msb <= 'f') ||
            (msb >= 'A' && msb <= 'F')) {
            return '00' + hexStr;
        } else {
            return hexStr;
        }
    }

    function toHex(number) {
        let nstr = number.toString(16);
        if (nstr.length % 2 == 0) return nstr;
        return '0' + nstr
    }

    // encode ASN.1 DER length field
    // if <=127, short form
    // if >=128, long form
    function encodeLengthHex(n) {
        if (n <= 127) return toHex(n);
        else {
            let n_hex = toHex(n);
            let length_of_length_byte = 128 + n_hex.length / 2; // 0x80+numbytes
            return toHex(length_of_length_byte) + n_hex
        }
    }

    let modulus = new Buffer(modulus_b64, 'base64');
    let exponent = new Buffer(exponent_b64, 'base64');

    let modulus_hex = modulus.toString('hex');
    let exponent_hex = exponent.toString('hex');

    modulus_hex = prepadSigned(modulus_hex);
    exponent_hex = prepadSigned(exponent_hex);

    let modlen = modulus_hex.length / 2;
    let explen = exponent_hex.length / 2;

    let encoded_modlen = encodeLengthHex(modlen);
    let encoded_explen = encodeLengthHex(explen);
    let encoded_pubkey = '30' +
        encodeLengthHex(
            modlen +
            explen +
            encoded_modlen.length / 2 +
            encoded_explen.length / 2 + 2
        ) +
        '02' + encoded_modlen + modulus_hex +
        '02' + encoded_explen + exponent_hex;

    let seq2 =
        '30 0d ' +
        '06 09 2a 86 48 86 f7 0d 01 01 01' +
        '05 00 ' +
        '03' + encodeLengthHex(encoded_pubkey.length / 2 + 1) +
        '00' + encoded_pubkey;

    seq2 = seq2.replace(/ /g, '');

    let der_hex = '30' + encodeLengthHex(seq2.length / 2) + seq2;

    der_hex = der_hex.replace(/ /g, '');

    let der = new Buffer(der_hex, 'hex');
    let der_b64 = der.toString('base64');

    return '-----BEGIN PUBLIC KEY-----\n'
        + der_b64.match(/.{1,64}/g).join('\n')
        + '\n-----END PUBLIC KEY-----\n';
}