diff --git a/ChangeLog.txt b/ChangeLog.txt index 2c6cc352..5372c5d8 100755 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,6 +1,12 @@ ChangeLog for jsrsasign +* Changes between 4.2.2 to 4.2.3 (2014-May-14) minor update + - keyutil 1.0.6 + - isPublic and isPrivate flag fix for generateKey method. + - tool_ca.html + - fix keyutil.js reference + * Changes between 4.2.1 to 4.2.2 (2014-Apr-19) - asn1x509 1.0.7 to 1.0.8 - add setSignatureHex method for Certificate class @@ -9,9 +15,9 @@ ChangeLog for jsrsasign - add AuthorityKeyIdentifier X.509v3 extension class - keyutil 1.0.4 to 1.0.5 - PKCS#10 CSR support. Following methods are added: - - PKCS5PKEY.getKeyFromCSRPEM - - PKCS5PKEY.getKeyFromCSRHex - - PKCS5PKEY.parseCSRHex + - KEYUTIL.getKeyFromCSRPEM + - KEYUTIL.getKeyFromCSRHex + - KEYUTIL.parseCSRHex - Tool: - tool_forfact.html: CSR to fake certificate converter for factorable.net diff --git a/api/files.html b/api/files.html index d067da99..0ea304dd 100755 --- a/api/files.html +++ b/api/files.html @@ -476,7 +476,7 @@
1 /*! keyutil-1.0.5.js (c) 2013-2014 Kenji Urushima | kjur.github.com/jsrsasign/license +1 /*! keyutil-1.0.6.js (c) 2013-2014 Kenji Urushima | kjur.github.com/jsrsasign/license 2 */ 3 /* 4 * keyutil.js - key utility for PKCS#1/5/8 PEM, RSA/DSA/ECDSA key object @@ -22,7 +22,7 @@ 15 * @fileOverview 16 * @name keyutil-1.0.js 17 * @author Kenji Urushima kenji.urushima@gmail.com - 18 * @version keyutil 1.0.5 (2014-Apr-18) + 18 * @version keyutil 1.0.6 (2014-May-14) 19 * @since jsrsasign 4.1.4 20 * @license <a href="http://kjur.github.io/jsrsasign/license/">MIT License</a> 21 */ @@ -1446,439 +1446,447 @@ 1439 var keylen = keylenOrCurve; 1440 var prvKey = new RSAKey(); 1441 prvKey.generate(keylen, '10001'); -1442 -1443 var pubKey = new RSAKey(); -1444 var hN = prvKey.n.toString(16); -1445 var hE = prvKey.e.toString(16); -1446 pubKey.setPublic(hN, hE); -1447 -1448 var result = {}; -1449 result.prvKeyObj = prvKey; -1450 result.pubKeyObj = pubKey; -1451 return result; -1452 } else if (alg == "EC") { -1453 var curve = keylenOrCurve; -1454 var ec = new KJUR.crypto.ECDSA({curve: curve}); -1455 var keypairHex = ec.generateKeyPairHex(); -1456 -1457 var prvKey = new KJUR.crypto.ECDSA({curve: curve}); -1458 prvKey.setPrivateKeyHex(keypairHex.ecprvhex); -1459 -1460 var pubKey = new KJUR.crypto.ECDSA({curve: curve}); -1461 pubKey.setPublicKeyHex(keypairHex.ecpubhex); -1462 -1463 var result = {}; -1464 result.prvKeyObj = prvKey; -1465 result.pubKeyObj = pubKey; -1466 return result; -1467 } else { -1468 throw "unknown algorithm: " + alg; -1469 } -1470 }; -1471 -1472 /** -1473 * get PEM formatted private or public key file from a RSA/ECDSA/DSA key object -1474 * @name getPEM -1475 * @memberOf KEYUTIL -1476 * @function -1477 * @static -1478 * @param {Object} keyObjOrHex key object {@link RSAKey}, {@link KJUR.crypto.ECDSA} or {@link KJUR.crypto.DSA} to encode to -1479 * @param {String} formatType (OPTION) output format type of "PKCS1PRV", "PKCS5PRV" or "PKCS8PRV" for private key -1480 * @param {String} passwd (OPTION) password to protect private key -1481 * @param {String} encAlg (OPTION) encryption algorithm for PKCS#5. currently supports DES-CBC, DES-EDE3-CBC and AES-{128,192,256}-CBC -1482 * @since keyutil 1.0.4 -1483 * @description -1484 * <dl> -1485 * <dt><b>NOTE1:</b> -1486 * <dd> -1487 * PKCS#5 encrypted private key protection algorithm supports DES-CBC, -1488 * DES-EDE3-CBC and AES-{128,192,256}-CBC -1489 * <dt><b>NOTE2:</b> -1490 * <dd> -1491 * OpenSSL supports -1492 * </dl> -1493 * @example -1494 * KEUUTIL.getPEM(publicKey) => generates PEM PKCS#8 public key -1495 * KEUUTIL.getPEM(privateKey, "PKCS1PRV") => generates PEM PKCS#1 plain private key -1496 * KEUUTIL.getPEM(privateKey, "PKCS5PRV", "pass") => generates PEM PKCS#5 encrypted private key -1497 * with DES-EDE3-CBC (DEFAULT) -1498 * KEUUTIL.getPEM(privateKey, "PKCS5PRV", "pass", "DES-CBC") => generates PEM PKCS#5 encrypted -1499 * private key with DES-CBC -1500 * KEUUTIL.getPEM(privateKey, "PKCS8PRV") => generates PEM PKCS#8 plain private key -1501 * KEUUTIL.getPEM(privateKey, "PKCS8PRV", "pass") => generates PEM PKCS#8 encrypted private key -1502 * with PBKDF2_HmacSHA1_3DES -1503 */ -1504 KEYUTIL.getPEM = function(keyObjOrHex, formatType, passwd, encAlg, hexType) { -1505 var ns1 = KJUR.asn1; -1506 var ns2 = KJUR.crypto; -1507 -1508 function _rsaprv2asn1obj(keyObjOrHex) { -1509 var asn1Obj = KJUR.asn1.ASN1Util.newObject({ -1510 "seq": [ -1511 {"int": 0 }, -1512 {"int": {"bigint": keyObjOrHex.n}}, -1513 {"int": keyObjOrHex.e}, -1514 {"int": {"bigint": keyObjOrHex.d}}, -1515 {"int": {"bigint": keyObjOrHex.p}}, -1516 {"int": {"bigint": keyObjOrHex.q}}, -1517 {"int": {"bigint": keyObjOrHex.dmp1}}, -1518 {"int": {"bigint": keyObjOrHex.dmq1}}, -1519 {"int": {"bigint": keyObjOrHex.coeff}} -1520 ] -1521 }); -1522 return asn1Obj; -1523 }; -1524 -1525 function _ecdsaprv2asn1obj(keyObjOrHex) { -1526 var asn1Obj2 = KJUR.asn1.ASN1Util.newObject({ -1527 "seq": [ -1528 {"int": 1 }, -1529 {"octstr": {"hex": keyObjOrHex.prvKeyHex}}, -1530 {"tag": ['a0', true, {'oid': {'name': keyObjOrHex.curveName}}]}, -1531 {"tag": ['a1', true, {'bitstr': {'hex': '00' + keyObjOrHex.pubKeyHex}}]} -1532 ] -1533 }); -1534 return asn1Obj2; -1535 }; -1536 -1537 function _dsaprv2asn1obj(keyObjOrHex) { -1538 var asn1Obj = KJUR.asn1.ASN1Util.newObject({ -1539 "seq": [ -1540 {"int": 0 }, -1541 {"int": {"bigint": keyObjOrHex.p}}, -1542 {"int": {"bigint": keyObjOrHex.q}}, -1543 {"int": {"bigint": keyObjOrHex.g}}, -1544 {"int": {"bigint": keyObjOrHex.y}}, -1545 {"int": {"bigint": keyObjOrHex.x}} -1546 ] -1547 }); -1548 return asn1Obj; -1549 }; -1550 -1551 // 1. public key -1552 -1553 // x. PEM PKCS#8 public key of RSA/ECDSA/DSA public key object -1554 if (((typeof RSAKey != "undefined" && keyObjOrHex instanceof RSAKey) || -1555 (typeof ns2.DSA != "undefined" && keyObjOrHex instanceof ns2.DSA) || -1556 (typeof ns2.ECDSA != "undefined" && keyObjOrHex instanceof ns2.ECDSA)) && -1557 keyObjOrHex.isPublic == true && -1558 (formatType === undefined || formatType == "PKCS8PUB")) { -1559 var asn1Obj = new KJUR.asn1.x509.SubjectPublicKeyInfo(keyObjOrHex); -1560 var asn1Hex = asn1Obj.getEncodedHex(); -1561 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex, "PUBLIC KEY"); -1562 } -1563 -1564 // 2. private -1565 -1566 // x. PEM PKCS#1 plain private key of RSA private key object -1567 if (formatType == "PKCS1PRV" && -1568 typeof RSAKey != "undefined" && -1569 keyObjOrHex instanceof RSAKey && -1570 (passwd === undefined || passwd == null) && -1571 keyObjOrHex.isPrivate == true) { -1572 -1573 var asn1Obj = _rsaprv2asn1obj(keyObjOrHex); -1574 var asn1Hex = asn1Obj.getEncodedHex(); -1575 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex, "RSA PRIVATE KEY"); -1576 } -1577 -1578 // x. PEM PKCS#1 plain private key of ECDSA private key object -1579 if (formatType == "PKCS1PRV" && -1580 typeof RSAKey != "undefined" && -1581 keyObjOrHex instanceof KJUR.crypto.ECDSA && -1582 (passwd === undefined || passwd == null) && -1583 keyObjOrHex.isPrivate == true) { -1584 -1585 var asn1Obj1 = new KJUR.asn1.DERObjectIdentifier({'name': keyObjOrHex.curveName}); -1586 var asn1Hex1 = asn1Obj1.getEncodedHex(); -1587 var asn1Obj2 = _ecdsaprv2asn1obj(keyObjOrHex); -1588 var asn1Hex2 = asn1Obj2.getEncodedHex(); -1589 -1590 var s = ""; -1591 s += ns1.ASN1Util.getPEMStringFromHex(asn1Hex1, "EC PARAMETERS"); -1592 s += ns1.ASN1Util.getPEMStringFromHex(asn1Hex2, "EC PRIVATE KEY"); -1593 return s; -1594 } -1595 -1596 // x. PEM PKCS#1 plain private key of DSA private key object -1597 if (formatType == "PKCS1PRV" && -1598 typeof KJUR.crypto.DSA != "undefined" && -1599 keyObjOrHex instanceof KJUR.crypto.DSA && -1600 (passwd === undefined || passwd == null) && -1601 keyObjOrHex.isPrivate == true) { -1602 -1603 var asn1Obj = _dsaprv2asn1obj(keyObjOrHex); -1604 var asn1Hex = asn1Obj.getEncodedHex(); -1605 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex, "DSA PRIVATE KEY"); -1606 } -1607 -1608 // 3. private -1609 -1610 // x. PEM PKCS#5 encrypted private key of RSA private key object -1611 if (formatType == "PKCS5PRV" && -1612 typeof RSAKey != "undefined" && -1613 keyObjOrHex instanceof RSAKey && -1614 (passwd !== undefined && passwd != null) && -1615 keyObjOrHex.isPrivate == true) { -1616 -1617 var asn1Obj = _rsaprv2asn1obj(keyObjOrHex); -1618 var asn1Hex = asn1Obj.getEncodedHex(); -1619 -1620 if (encAlg === undefined) encAlg = "DES-EDE3-CBC"; -1621 return this.getEncryptedPKCS5PEMFromPrvKeyHex("RSA", asn1Hex, passwd, encAlg); -1622 } -1623 -1624 // x. PEM PKCS#5 encrypted private key of ECDSA private key object -1625 if (formatType == "PKCS5PRV" && -1626 typeof KJUR.crypto.ECDSA != "undefined" && -1627 keyObjOrHex instanceof KJUR.crypto.ECDSA && -1628 (passwd !== undefined && passwd != null) && -1629 keyObjOrHex.isPrivate == true) { -1630 -1631 var asn1Obj = _ecdsaprv2asn1obj(keyObjOrHex); -1632 var asn1Hex = asn1Obj.getEncodedHex(); -1633 -1634 if (encAlg === undefined) encAlg = "DES-EDE3-CBC"; -1635 return this.getEncryptedPKCS5PEMFromPrvKeyHex("EC", asn1Hex, passwd, encAlg); -1636 } -1637 -1638 // x. PEM PKCS#5 encrypted private key of DSA private key object -1639 if (formatType == "PKCS5PRV" && -1640 typeof KJUR.crypto.DSA != "undefined" && -1641 keyObjOrHex instanceof KJUR.crypto.DSA && -1642 (passwd !== undefined && passwd != null) && -1643 keyObjOrHex.isPrivate == true) { -1644 -1645 var asn1Obj = _dsaprv2asn1obj(keyObjOrHex); -1646 var asn1Hex = asn1Obj.getEncodedHex(); -1647 -1648 if (encAlg === undefined) encAlg = "DES-EDE3-CBC"; -1649 return this.getEncryptedPKCS5PEMFromPrvKeyHex("DSA", asn1Hex, passwd, encAlg); -1650 } -1651 -1652 // x. ====================================================================== -1653 -1654 var _getEncryptedPKCS8 = function(plainKeyHex, passcode) { -1655 var info = _getEencryptedPKCS8Info(plainKeyHex, passcode); -1656 //alert("iv=" + info.encryptionSchemeIV); -1657 //alert("info.ciphertext2[" + info.ciphertext.length + "=" + info.ciphertext); -1658 var asn1Obj = new KJUR.asn1.ASN1Util.newObject({ -1659 "seq": [ -1660 {"seq": [ -1661 {"oid": {"name": "pkcs5PBES2"}}, -1662 {"seq": [ -1663 {"seq": [ -1664 {"oid": {"name": "pkcs5PBKDF2"}}, -1665 {"seq": [ -1666 {"octstr": {"hex": info.pbkdf2Salt}}, -1667 {"int": info.pbkdf2Iter} -1668 ]} -1669 ]}, -1670 {"seq": [ -1671 {"oid": {"name": "des-EDE3-CBC"}}, -1672 {"octstr": {"hex": info.encryptionSchemeIV}} -1673 ]} -1674 ]} -1675 ]}, -1676 {"octstr": {"hex": info.ciphertext}} -1677 ] -1678 }); -1679 return asn1Obj.getEncodedHex(); -1680 }; -1681 -1682 var _getEencryptedPKCS8Info = function(plainKeyHex, passcode) { -1683 var pbkdf2Iter = 100; -1684 var pbkdf2SaltWS = CryptoJS.lib.WordArray.random(8); -1685 var encryptionSchemeAlg = "DES-EDE3-CBC"; -1686 var encryptionSchemeIVWS = CryptoJS.lib.WordArray.random(8); -1687 // PBKDF2 key -1688 var pbkdf2KeyWS = CryptoJS.PBKDF2(passcode, -1689 pbkdf2SaltWS, { "keySize": 192/32, -1690 "iterations": pbkdf2Iter }); -1691 // ENCRYPT -1692 var plainKeyWS = CryptoJS.enc.Hex.parse(plainKeyHex); -1693 var encryptedKeyHex = -1694 CryptoJS.TripleDES.encrypt(plainKeyWS, pbkdf2KeyWS, { "iv": encryptionSchemeIVWS }) + ""; -1695 -1696 //alert("encryptedKeyHex=" + encryptedKeyHex); -1697 -1698 var info = {}; -1699 info.ciphertext = encryptedKeyHex; -1700 //alert("info.ciphertext=" + info.ciphertext); -1701 info.pbkdf2Salt = CryptoJS.enc.Hex.stringify(pbkdf2SaltWS); -1702 info.pbkdf2Iter = pbkdf2Iter; -1703 info.encryptionSchemeAlg = encryptionSchemeAlg; -1704 info.encryptionSchemeIV = CryptoJS.enc.Hex.stringify(encryptionSchemeIVWS); -1705 return info; -1706 }; -1707 -1708 // x. PEM PKCS#8 plain private key of RSA private key object -1709 if (formatType == "PKCS8PRV" && -1710 typeof RSAKey != "undefined" && -1711 keyObjOrHex instanceof RSAKey && -1712 keyObjOrHex.isPrivate == true) { -1713 -1714 var keyObj = _rsaprv2asn1obj(keyObjOrHex); -1715 var keyHex = keyObj.getEncodedHex(); -1716 -1717 var asn1Obj = KJUR.asn1.ASN1Util.newObject({ -1718 "seq": [ -1719 {"int": 0}, -1720 {"seq": [{"oid": {"name": "rsaEncryption"}},{"null": true}]}, -1721 {"octstr": {"hex": keyHex}} -1722 ] -1723 }); -1724 var asn1Hex = asn1Obj.getEncodedHex(); -1725 -1726 if (passwd === undefined || passwd == null) { -1727 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex, "PRIVATE KEY"); -1728 } else { -1729 var asn1Hex2 = _getEncryptedPKCS8(asn1Hex, passwd); -1730 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex2, "ENCRYPTED PRIVATE KEY"); -1731 } -1732 } +1442 prvKey.isPrivate = true; +1443 prvKey.isPublic = true; +1444 +1445 var pubKey = new RSAKey(); +1446 var hN = prvKey.n.toString(16); +1447 var hE = prvKey.e.toString(16); +1448 pubKey.setPublic(hN, hE); +1449 pubKey.isPrivate = false; +1450 pubKey.isPublic = true; +1451 +1452 var result = {}; +1453 result.prvKeyObj = prvKey; +1454 result.pubKeyObj = pubKey; +1455 return result; +1456 } else if (alg == "EC") { +1457 var curve = keylenOrCurve; +1458 var ec = new KJUR.crypto.ECDSA({curve: curve}); +1459 var keypairHex = ec.generateKeyPairHex(); +1460 +1461 var prvKey = new KJUR.crypto.ECDSA({curve: curve}); +1462 prvKey.setPrivateKeyHex(keypairHex.ecprvhex); +1463 prvKey.isPrivate = true; +1464 prvKey.isPublic = false; +1465 +1466 var pubKey = new KJUR.crypto.ECDSA({curve: curve}); +1467 pubKey.setPublicKeyHex(keypairHex.ecpubhex); +1468 pubKey.isPrivate = false; +1469 pubKey.isPublic = true; +1470 +1471 var result = {}; +1472 result.prvKeyObj = prvKey; +1473 result.pubKeyObj = pubKey; +1474 return result; +1475 } else { +1476 throw "unknown algorithm: " + alg; +1477 } +1478 }; +1479 +1480 /** +1481 * get PEM formatted private or public key file from a RSA/ECDSA/DSA key object +1482 * @name getPEM +1483 * @memberOf KEYUTIL +1484 * @function +1485 * @static +1486 * @param {Object} keyObjOrHex key object {@link RSAKey}, {@link KJUR.crypto.ECDSA} or {@link KJUR.crypto.DSA} to encode to +1487 * @param {String} formatType (OPTION) output format type of "PKCS1PRV", "PKCS5PRV" or "PKCS8PRV" for private key +1488 * @param {String} passwd (OPTION) password to protect private key +1489 * @param {String} encAlg (OPTION) encryption algorithm for PKCS#5. currently supports DES-CBC, DES-EDE3-CBC and AES-{128,192,256}-CBC +1490 * @since keyutil 1.0.4 +1491 * @description +1492 * <dl> +1493 * <dt><b>NOTE1:</b> +1494 * <dd> +1495 * PKCS#5 encrypted private key protection algorithm supports DES-CBC, +1496 * DES-EDE3-CBC and AES-{128,192,256}-CBC +1497 * <dt><b>NOTE2:</b> +1498 * <dd> +1499 * OpenSSL supports +1500 * </dl> +1501 * @example +1502 * KEUUTIL.getPEM(publicKey) => generates PEM PKCS#8 public key +1503 * KEUUTIL.getPEM(privateKey, "PKCS1PRV") => generates PEM PKCS#1 plain private key +1504 * KEUUTIL.getPEM(privateKey, "PKCS5PRV", "pass") => generates PEM PKCS#5 encrypted private key +1505 * with DES-EDE3-CBC (DEFAULT) +1506 * KEUUTIL.getPEM(privateKey, "PKCS5PRV", "pass", "DES-CBC") => generates PEM PKCS#5 encrypted +1507 * private key with DES-CBC +1508 * KEUUTIL.getPEM(privateKey, "PKCS8PRV") => generates PEM PKCS#8 plain private key +1509 * KEUUTIL.getPEM(privateKey, "PKCS8PRV", "pass") => generates PEM PKCS#8 encrypted private key +1510 * with PBKDF2_HmacSHA1_3DES +1511 */ +1512 KEYUTIL.getPEM = function(keyObjOrHex, formatType, passwd, encAlg, hexType) { +1513 var ns1 = KJUR.asn1; +1514 var ns2 = KJUR.crypto; +1515 +1516 function _rsaprv2asn1obj(keyObjOrHex) { +1517 var asn1Obj = KJUR.asn1.ASN1Util.newObject({ +1518 "seq": [ +1519 {"int": 0 }, +1520 {"int": {"bigint": keyObjOrHex.n}}, +1521 {"int": keyObjOrHex.e}, +1522 {"int": {"bigint": keyObjOrHex.d}}, +1523 {"int": {"bigint": keyObjOrHex.p}}, +1524 {"int": {"bigint": keyObjOrHex.q}}, +1525 {"int": {"bigint": keyObjOrHex.dmp1}}, +1526 {"int": {"bigint": keyObjOrHex.dmq1}}, +1527 {"int": {"bigint": keyObjOrHex.coeff}} +1528 ] +1529 }); +1530 return asn1Obj; +1531 }; +1532 +1533 function _ecdsaprv2asn1obj(keyObjOrHex) { +1534 var asn1Obj2 = KJUR.asn1.ASN1Util.newObject({ +1535 "seq": [ +1536 {"int": 1 }, +1537 {"octstr": {"hex": keyObjOrHex.prvKeyHex}}, +1538 {"tag": ['a0', true, {'oid': {'name': keyObjOrHex.curveName}}]}, +1539 {"tag": ['a1', true, {'bitstr': {'hex': '00' + keyObjOrHex.pubKeyHex}}]} +1540 ] +1541 }); +1542 return asn1Obj2; +1543 }; +1544 +1545 function _dsaprv2asn1obj(keyObjOrHex) { +1546 var asn1Obj = KJUR.asn1.ASN1Util.newObject({ +1547 "seq": [ +1548 {"int": 0 }, +1549 {"int": {"bigint": keyObjOrHex.p}}, +1550 {"int": {"bigint": keyObjOrHex.q}}, +1551 {"int": {"bigint": keyObjOrHex.g}}, +1552 {"int": {"bigint": keyObjOrHex.y}}, +1553 {"int": {"bigint": keyObjOrHex.x}} +1554 ] +1555 }); +1556 return asn1Obj; +1557 }; +1558 +1559 // 1. public key +1560 +1561 // x. PEM PKCS#8 public key of RSA/ECDSA/DSA public key object +1562 if (((typeof RSAKey != "undefined" && keyObjOrHex instanceof RSAKey) || +1563 (typeof ns2.DSA != "undefined" && keyObjOrHex instanceof ns2.DSA) || +1564 (typeof ns2.ECDSA != "undefined" && keyObjOrHex instanceof ns2.ECDSA)) && +1565 keyObjOrHex.isPublic == true && +1566 (formatType === undefined || formatType == "PKCS8PUB")) { +1567 var asn1Obj = new KJUR.asn1.x509.SubjectPublicKeyInfo(keyObjOrHex); +1568 var asn1Hex = asn1Obj.getEncodedHex(); +1569 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex, "PUBLIC KEY"); +1570 } +1571 +1572 // 2. private +1573 +1574 // x. PEM PKCS#1 plain private key of RSA private key object +1575 if (formatType == "PKCS1PRV" && +1576 typeof RSAKey != "undefined" && +1577 keyObjOrHex instanceof RSAKey && +1578 (passwd === undefined || passwd == null) && +1579 keyObjOrHex.isPrivate == true) { +1580 +1581 var asn1Obj = _rsaprv2asn1obj(keyObjOrHex); +1582 var asn1Hex = asn1Obj.getEncodedHex(); +1583 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex, "RSA PRIVATE KEY"); +1584 } +1585 +1586 // x. PEM PKCS#1 plain private key of ECDSA private key object +1587 if (formatType == "PKCS1PRV" && +1588 typeof RSAKey != "undefined" && +1589 keyObjOrHex instanceof KJUR.crypto.ECDSA && +1590 (passwd === undefined || passwd == null) && +1591 keyObjOrHex.isPrivate == true) { +1592 +1593 var asn1Obj1 = new KJUR.asn1.DERObjectIdentifier({'name': keyObjOrHex.curveName}); +1594 var asn1Hex1 = asn1Obj1.getEncodedHex(); +1595 var asn1Obj2 = _ecdsaprv2asn1obj(keyObjOrHex); +1596 var asn1Hex2 = asn1Obj2.getEncodedHex(); +1597 +1598 var s = ""; +1599 s += ns1.ASN1Util.getPEMStringFromHex(asn1Hex1, "EC PARAMETERS"); +1600 s += ns1.ASN1Util.getPEMStringFromHex(asn1Hex2, "EC PRIVATE KEY"); +1601 return s; +1602 } +1603 +1604 // x. PEM PKCS#1 plain private key of DSA private key object +1605 if (formatType == "PKCS1PRV" && +1606 typeof KJUR.crypto.DSA != "undefined" && +1607 keyObjOrHex instanceof KJUR.crypto.DSA && +1608 (passwd === undefined || passwd == null) && +1609 keyObjOrHex.isPrivate == true) { +1610 +1611 var asn1Obj = _dsaprv2asn1obj(keyObjOrHex); +1612 var asn1Hex = asn1Obj.getEncodedHex(); +1613 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex, "DSA PRIVATE KEY"); +1614 } +1615 +1616 // 3. private +1617 +1618 // x. PEM PKCS#5 encrypted private key of RSA private key object +1619 if (formatType == "PKCS5PRV" && +1620 typeof RSAKey != "undefined" && +1621 keyObjOrHex instanceof RSAKey && +1622 (passwd !== undefined && passwd != null) && +1623 keyObjOrHex.isPrivate == true) { +1624 +1625 var asn1Obj = _rsaprv2asn1obj(keyObjOrHex); +1626 var asn1Hex = asn1Obj.getEncodedHex(); +1627 +1628 if (encAlg === undefined) encAlg = "DES-EDE3-CBC"; +1629 return this.getEncryptedPKCS5PEMFromPrvKeyHex("RSA", asn1Hex, passwd, encAlg); +1630 } +1631 +1632 // x. PEM PKCS#5 encrypted private key of ECDSA private key object +1633 if (formatType == "PKCS5PRV" && +1634 typeof KJUR.crypto.ECDSA != "undefined" && +1635 keyObjOrHex instanceof KJUR.crypto.ECDSA && +1636 (passwd !== undefined && passwd != null) && +1637 keyObjOrHex.isPrivate == true) { +1638 +1639 var asn1Obj = _ecdsaprv2asn1obj(keyObjOrHex); +1640 var asn1Hex = asn1Obj.getEncodedHex(); +1641 +1642 if (encAlg === undefined) encAlg = "DES-EDE3-CBC"; +1643 return this.getEncryptedPKCS5PEMFromPrvKeyHex("EC", asn1Hex, passwd, encAlg); +1644 } +1645 +1646 // x. PEM PKCS#5 encrypted private key of DSA private key object +1647 if (formatType == "PKCS5PRV" && +1648 typeof KJUR.crypto.DSA != "undefined" && +1649 keyObjOrHex instanceof KJUR.crypto.DSA && +1650 (passwd !== undefined && passwd != null) && +1651 keyObjOrHex.isPrivate == true) { +1652 +1653 var asn1Obj = _dsaprv2asn1obj(keyObjOrHex); +1654 var asn1Hex = asn1Obj.getEncodedHex(); +1655 +1656 if (encAlg === undefined) encAlg = "DES-EDE3-CBC"; +1657 return this.getEncryptedPKCS5PEMFromPrvKeyHex("DSA", asn1Hex, passwd, encAlg); +1658 } +1659 +1660 // x. ====================================================================== +1661 +1662 var _getEncryptedPKCS8 = function(plainKeyHex, passcode) { +1663 var info = _getEencryptedPKCS8Info(plainKeyHex, passcode); +1664 //alert("iv=" + info.encryptionSchemeIV); +1665 //alert("info.ciphertext2[" + info.ciphertext.length + "=" + info.ciphertext); +1666 var asn1Obj = new KJUR.asn1.ASN1Util.newObject({ +1667 "seq": [ +1668 {"seq": [ +1669 {"oid": {"name": "pkcs5PBES2"}}, +1670 {"seq": [ +1671 {"seq": [ +1672 {"oid": {"name": "pkcs5PBKDF2"}}, +1673 {"seq": [ +1674 {"octstr": {"hex": info.pbkdf2Salt}}, +1675 {"int": info.pbkdf2Iter} +1676 ]} +1677 ]}, +1678 {"seq": [ +1679 {"oid": {"name": "des-EDE3-CBC"}}, +1680 {"octstr": {"hex": info.encryptionSchemeIV}} +1681 ]} +1682 ]} +1683 ]}, +1684 {"octstr": {"hex": info.ciphertext}} +1685 ] +1686 }); +1687 return asn1Obj.getEncodedHex(); +1688 }; +1689 +1690 var _getEencryptedPKCS8Info = function(plainKeyHex, passcode) { +1691 var pbkdf2Iter = 100; +1692 var pbkdf2SaltWS = CryptoJS.lib.WordArray.random(8); +1693 var encryptionSchemeAlg = "DES-EDE3-CBC"; +1694 var encryptionSchemeIVWS = CryptoJS.lib.WordArray.random(8); +1695 // PBKDF2 key +1696 var pbkdf2KeyWS = CryptoJS.PBKDF2(passcode, +1697 pbkdf2SaltWS, { "keySize": 192/32, +1698 "iterations": pbkdf2Iter }); +1699 // ENCRYPT +1700 var plainKeyWS = CryptoJS.enc.Hex.parse(plainKeyHex); +1701 var encryptedKeyHex = +1702 CryptoJS.TripleDES.encrypt(plainKeyWS, pbkdf2KeyWS, { "iv": encryptionSchemeIVWS }) + ""; +1703 +1704 //alert("encryptedKeyHex=" + encryptedKeyHex); +1705 +1706 var info = {}; +1707 info.ciphertext = encryptedKeyHex; +1708 //alert("info.ciphertext=" + info.ciphertext); +1709 info.pbkdf2Salt = CryptoJS.enc.Hex.stringify(pbkdf2SaltWS); +1710 info.pbkdf2Iter = pbkdf2Iter; +1711 info.encryptionSchemeAlg = encryptionSchemeAlg; +1712 info.encryptionSchemeIV = CryptoJS.enc.Hex.stringify(encryptionSchemeIVWS); +1713 return info; +1714 }; +1715 +1716 // x. PEM PKCS#8 plain private key of RSA private key object +1717 if (formatType == "PKCS8PRV" && +1718 typeof RSAKey != "undefined" && +1719 keyObjOrHex instanceof RSAKey && +1720 keyObjOrHex.isPrivate == true) { +1721 +1722 var keyObj = _rsaprv2asn1obj(keyObjOrHex); +1723 var keyHex = keyObj.getEncodedHex(); +1724 +1725 var asn1Obj = KJUR.asn1.ASN1Util.newObject({ +1726 "seq": [ +1727 {"int": 0}, +1728 {"seq": [{"oid": {"name": "rsaEncryption"}},{"null": true}]}, +1729 {"octstr": {"hex": keyHex}} +1730 ] +1731 }); +1732 var asn1Hex = asn1Obj.getEncodedHex(); 1733 -1734 // x. PEM PKCS#8 plain private key of ECDSA private key object -1735 if (formatType == "PKCS8PRV" && -1736 typeof KJUR.crypto.ECDSA != "undefined" && -1737 keyObjOrHex instanceof KJUR.crypto.ECDSA && -1738 keyObjOrHex.isPrivate == true) { -1739 -1740 var keyObj = new KJUR.asn1.ASN1Util.newObject({ -1741 "seq": [ -1742 {"int": 1}, -1743 {"octstr": {"hex": keyObjOrHex.prvKeyHex}}, -1744 {"tag": ['a1', true, {"bitstr": {"hex": "00" + keyObjOrHex.pubKeyHex}}]} -1745 ] -1746 }); -1747 var keyHex = keyObj.getEncodedHex(); -1748 -1749 var asn1Obj = KJUR.asn1.ASN1Util.newObject({ -1750 "seq": [ -1751 {"int": 0}, -1752 {"seq": [ -1753 {"oid": {"name": "ecPublicKey"}}, -1754 {"oid": {"name": keyObjOrHex.curveName}} -1755 ]}, -1756 {"octstr": {"hex": keyHex}} -1757 ] -1758 }); -1759 -1760 var asn1Hex = asn1Obj.getEncodedHex(); -1761 if (passwd === undefined || passwd == null) { -1762 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex, "PRIVATE KEY"); -1763 } else { -1764 var asn1Hex2 = _getEncryptedPKCS8(asn1Hex, passwd); -1765 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex2, "ENCRYPTED PRIVATE KEY"); -1766 } -1767 } -1768 -1769 // x. PEM PKCS#8 plain private key of DSA private key object -1770 if (formatType == "PKCS8PRV" && -1771 typeof KJUR.crypto.DSA != "undefined" && -1772 keyObjOrHex instanceof KJUR.crypto.DSA && -1773 keyObjOrHex.isPrivate == true) { -1774 -1775 var keyObj = new KJUR.asn1.DERInteger({'bigint': keyObjOrHex.x}); -1776 var keyHex = keyObj.getEncodedHex(); -1777 -1778 var asn1Obj = KJUR.asn1.ASN1Util.newObject({ -1779 "seq": [ -1780 {"int": 0}, -1781 {"seq": [ -1782 {"oid": {"name": "dsa"}}, -1783 {"seq": [ -1784 {"int": {"bigint": keyObjOrHex.p}}, -1785 {"int": {"bigint": keyObjOrHex.q}}, -1786 {"int": {"bigint": keyObjOrHex.g}} -1787 ]} -1788 ]}, -1789 {"octstr": {"hex": keyHex}} -1790 ] -1791 }); -1792 -1793 var asn1Hex = asn1Obj.getEncodedHex(); -1794 if (passwd === undefined || passwd == null) { -1795 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex, "PRIVATE KEY"); -1796 } else { -1797 var asn1Hex2 = _getEncryptedPKCS8(asn1Hex, passwd); -1798 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex2, "ENCRYPTED PRIVATE KEY"); -1799 } -1800 } -1801 -1802 throw "unsupported object nor format"; -1803 }; -1804 -1805 // -- PUBLIC METHODS FOR CSR ------------------------------------------------------- -1806 -1807 /** -1808 * get RSAKey/DSA/ECDSA public key object from PEM formatted PKCS#10 CSR string -1809 * @name getKeyFromCSRPEM -1810 * @memberOf KEYUTIL -1811 * @function -1812 * @param {String} csrPEM PEM formatted PKCS#10 CSR string -1813 * @return {Object} RSAKey/DSA/ECDSA public key object -1814 * @since keyutil 1.0.5 -1815 */ -1816 KEYUTIL.getKeyFromCSRPEM = function(csrPEM) { -1817 var csrHex = KEYUTIL.getHexFromPEM(csrPEM, "CERTIFICATE REQUEST"); -1818 var key = KEYUTIL.getKeyFromCSRHex(csrHex); -1819 return key; -1820 }; -1821 -1822 /** -1823 * get RSAKey/DSA/ECDSA public key object from hexadecimal string of PKCS#10 CSR -1824 * @name getKeyFromCSRHex -1825 * @memberOf KEYUTIL -1826 * @function -1827 * @param {String} csrHex hexadecimal string of PKCS#10 CSR -1828 * @return {Object} RSAKey/DSA/ECDSA public key object -1829 * @since keyutil 1.0.5 -1830 */ -1831 KEYUTIL.getKeyFromCSRHex = function(csrHex) { -1832 var info = KEYUTIL.parseCSRHex(csrHex); -1833 var key = KEYUTIL.getKey(info.p8pubkeyhex, null, "pkcs8pub"); -1834 return key; -1835 }; -1836 -1837 /** -1838 * parse hexadecimal string of PKCS#10 CSR (certificate signing request) -1839 * @name parseCSRHex -1840 * @memberOf KEYUTIL -1841 * @function -1842 * @param {String} csrHex hexadecimal string of PKCS#10 CSR -1843 * @return {Array} associative array of parsed CSR -1844 * @since keyutil 1.0.5 -1845 * @description -1846 * Resulted associative array has following properties: -1847 * <ul> -1848 * <li>p8pubkeyhex - hexadecimal string of subject public key in PKCS#8</li> -1849 * </ul> -1850 */ -1851 KEYUTIL.parseCSRHex = function(csrHex) { -1852 var result = {}; -1853 var h = csrHex; -1854 -1855 // 1. sequence -1856 if (h.substr(0, 2) != "30") -1857 throw "malformed CSR(code:001)"; // not sequence -1858 -1859 var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(h, 0); -1860 if (a1.length < 1) -1861 throw "malformed CSR(code:002)"; // short length +1734 if (passwd === undefined || passwd == null) { +1735 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex, "PRIVATE KEY"); +1736 } else { +1737 var asn1Hex2 = _getEncryptedPKCS8(asn1Hex, passwd); +1738 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex2, "ENCRYPTED PRIVATE KEY"); +1739 } +1740 } +1741 +1742 // x. PEM PKCS#8 plain private key of ECDSA private key object +1743 if (formatType == "PKCS8PRV" && +1744 typeof KJUR.crypto.ECDSA != "undefined" && +1745 keyObjOrHex instanceof KJUR.crypto.ECDSA && +1746 keyObjOrHex.isPrivate == true) { +1747 +1748 var keyObj = new KJUR.asn1.ASN1Util.newObject({ +1749 "seq": [ +1750 {"int": 1}, +1751 {"octstr": {"hex": keyObjOrHex.prvKeyHex}}, +1752 {"tag": ['a1', true, {"bitstr": {"hex": "00" + keyObjOrHex.pubKeyHex}}]} +1753 ] +1754 }); +1755 var keyHex = keyObj.getEncodedHex(); +1756 +1757 var asn1Obj = KJUR.asn1.ASN1Util.newObject({ +1758 "seq": [ +1759 {"int": 0}, +1760 {"seq": [ +1761 {"oid": {"name": "ecPublicKey"}}, +1762 {"oid": {"name": keyObjOrHex.curveName}} +1763 ]}, +1764 {"octstr": {"hex": keyHex}} +1765 ] +1766 }); +1767 +1768 var asn1Hex = asn1Obj.getEncodedHex(); +1769 if (passwd === undefined || passwd == null) { +1770 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex, "PRIVATE KEY"); +1771 } else { +1772 var asn1Hex2 = _getEncryptedPKCS8(asn1Hex, passwd); +1773 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex2, "ENCRYPTED PRIVATE KEY"); +1774 } +1775 } +1776 +1777 // x. PEM PKCS#8 plain private key of DSA private key object +1778 if (formatType == "PKCS8PRV" && +1779 typeof KJUR.crypto.DSA != "undefined" && +1780 keyObjOrHex instanceof KJUR.crypto.DSA && +1781 keyObjOrHex.isPrivate == true) { +1782 +1783 var keyObj = new KJUR.asn1.DERInteger({'bigint': keyObjOrHex.x}); +1784 var keyHex = keyObj.getEncodedHex(); +1785 +1786 var asn1Obj = KJUR.asn1.ASN1Util.newObject({ +1787 "seq": [ +1788 {"int": 0}, +1789 {"seq": [ +1790 {"oid": {"name": "dsa"}}, +1791 {"seq": [ +1792 {"int": {"bigint": keyObjOrHex.p}}, +1793 {"int": {"bigint": keyObjOrHex.q}}, +1794 {"int": {"bigint": keyObjOrHex.g}} +1795 ]} +1796 ]}, +1797 {"octstr": {"hex": keyHex}} +1798 ] +1799 }); +1800 +1801 var asn1Hex = asn1Obj.getEncodedHex(); +1802 if (passwd === undefined || passwd == null) { +1803 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex, "PRIVATE KEY"); +1804 } else { +1805 var asn1Hex2 = _getEncryptedPKCS8(asn1Hex, passwd); +1806 return ns1.ASN1Util.getPEMStringFromHex(asn1Hex2, "ENCRYPTED PRIVATE KEY"); +1807 } +1808 } +1809 +1810 throw "unsupported object nor format"; +1811 }; +1812 +1813 // -- PUBLIC METHODS FOR CSR ------------------------------------------------------- +1814 +1815 /** +1816 * get RSAKey/DSA/ECDSA public key object from PEM formatted PKCS#10 CSR string +1817 * @name getKeyFromCSRPEM +1818 * @memberOf KEYUTIL +1819 * @function +1820 * @param {String} csrPEM PEM formatted PKCS#10 CSR string +1821 * @return {Object} RSAKey/DSA/ECDSA public key object +1822 * @since keyutil 1.0.5 +1823 */ +1824 KEYUTIL.getKeyFromCSRPEM = function(csrPEM) { +1825 var csrHex = KEYUTIL.getHexFromPEM(csrPEM, "CERTIFICATE REQUEST"); +1826 var key = KEYUTIL.getKeyFromCSRHex(csrHex); +1827 return key; +1828 }; +1829 +1830 /** +1831 * get RSAKey/DSA/ECDSA public key object from hexadecimal string of PKCS#10 CSR +1832 * @name getKeyFromCSRHex +1833 * @memberOf KEYUTIL +1834 * @function +1835 * @param {String} csrHex hexadecimal string of PKCS#10 CSR +1836 * @return {Object} RSAKey/DSA/ECDSA public key object +1837 * @since keyutil 1.0.5 +1838 */ +1839 KEYUTIL.getKeyFromCSRHex = function(csrHex) { +1840 var info = KEYUTIL.parseCSRHex(csrHex); +1841 var key = KEYUTIL.getKey(info.p8pubkeyhex, null, "pkcs8pub"); +1842 return key; +1843 }; +1844 +1845 /** +1846 * parse hexadecimal string of PKCS#10 CSR (certificate signing request) +1847 * @name parseCSRHex +1848 * @memberOf KEYUTIL +1849 * @function +1850 * @param {String} csrHex hexadecimal string of PKCS#10 CSR +1851 * @return {Array} associative array of parsed CSR +1852 * @since keyutil 1.0.5 +1853 * @description +1854 * Resulted associative array has following properties: +1855 * <ul> +1856 * <li>p8pubkeyhex - hexadecimal string of subject public key in PKCS#8</li> +1857 * </ul> +1858 */ +1859 KEYUTIL.parseCSRHex = function(csrHex) { +1860 var result = {}; +1861 var h = csrHex; 1862 -1863 // 2. 2nd sequence -1864 if (h.substr(a1[0], 2) != "30") -1865 throw "malformed CSR(code:003)"; // not sequence +1863 // 1. sequence +1864 if (h.substr(0, 2) != "30") +1865 throw "malformed CSR(code:001)"; // not sequence 1866 -1867 var a2 = ASN1HEX.getPosArrayOfChildren_AtObj(h, a1[0]); -1868 if (a2.length < 3) -1869 throw "malformed CSR(code:004)"; // 2nd seq short elem +1867 var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(h, 0); +1868 if (a1.length < 1) +1869 throw "malformed CSR(code:002)"; // short length 1870 -1871 result.p8pubkeyhex = ASN1HEX.getHexOfTLV_AtObj(h, a2[2]); -1872 -1873 return result; -1874 }; -1875 -1876 -1877