digitalbazaar / forge

A native implementation of TLS in Javascript and tools to write crypto-based and network-heavy webapps
https://digitalbazaar.com/
Other
5.06k stars 784 forks source link

certificate verification?? #543

Open lbcsultan opened 6 years ago

lbcsultan commented 6 years ago

Hi,

I have generated a self-signed certificate cert as follows.

cert.sign(privateKey);

And I tried to verify it like

var verified = publicKey.verify(cert); console.log('Verification of cert: '+verified);

but it shows error as follows.

F:\AppliedCrypto\forge>node cert.js F:\AppliedCrypto\forge\node_modules\node-forge\lib\rsa.js:535 if(ed.length !== k) { ^

TypeError: Cannot read property 'length' of undefined at Object.pki.rsa.decrypt (F:\AppliedCrypto\forge\node_modules\node-forge\lib\rsa.js:535:8) at Object.key.verify (F:\AppliedCrypto\forge\node_modules\node-forge\lib\rsa.js:1076:22) at Object. (F:\AppliedCrypto\forge\cert.js:104:26) at Module._compile (module.js:569:30) at Object.Module._extensions..js (module.js:580:10) at Module.load (module.js:503:32) at tryModuleLoad (module.js:466:12) at Function.Module._load (module.js:458:3) at Function.Module.runMain (module.js:605:10) at startup (bootstrap_node.js:158:16)

What is the correct verification of certificate? What is the meaning of the following in the document?

// verifies an issued certificate using the certificates public key var verified = issuer.verify(issued);

davidlehn commented 6 years ago

Can you provide an executable script? Easier to help find the problem if we can see all the code. Thanks.

lbcsultan commented 6 years ago
var forge = require('node-forge');
var pki = forge.pki;

// generate a keypair and create an X.509v3 certificate
var keys = pki.rsa.generateKeyPair(2048);
var cert = pki.createCertificate();
cert.publicKey = keys.publicKey;
// alternatively set public key from a csr
//cert.publicKey = csr.publicKey;
cert.serialNumber = '01';
cert.validity.notBefore = new Date();
cert.validity.notAfter = new Date();
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);
var attrs = [{
  name: 'commonName',
  value: 'example.org'
}, {
  name: 'countryName',
  value: 'US'
}, {
  shortName: 'ST',
  value: 'Virginia'
}, {
  name: 'localityName',
  value: 'Blacksburg'
}, {
  name: 'organizationName',
  value: 'Test'
}, {
  shortName: 'OU',
  value: 'Test'
}];
cert.setSubject(attrs);
// alternatively set subject from a csr
//cert.setSubject(csr.subject.attributes);
cert.setIssuer(attrs);
cert.setExtensions([{
  name: 'basicConstraints',
  cA: true
}, {
  name: 'keyUsage',
  keyCertSign: true,
  digitalSignature: true,
  nonRepudiation: true,
  keyEncipherment: true,
  dataEncipherment: true
}, {
  name: 'extKeyUsage',
  serverAuth: true,
  clientAuth: true,
  codeSigning: true,
  emailProtection: true,
  timeStamping: true
}, {
  name: 'nsCertType',
  client: true,
  server: true,
  email: true,
  objsign: true,
  sslCA: true,
  emailCA: true,
  objCA: true
}, {
  name: 'subjectAltName',
  altNames: [{
    type: 6, // URI
    value: 'http://example.org/webid#me'
  }, {
    type: 7, // IP
    ip: '127.0.0.1'
  }]
}, {
  name: 'subjectKeyIdentifier'
}]);
/* alternatively set extensions from a csr
var extensions = csr.getAttribute({name: 'extensionRequest'}).extensions;
// optionally add more extensions
extensions.push.apply(extensions, [{
  name: 'basicConstraints',
  cA: true
}, {
  name: 'keyUsage',
  keyCertSign: true,
  digitalSignature: true,
  nonRepudiation: true,
  keyEncipherment: true,
  dataEncipherment: true
}]);
cert.setExtensions(extensions);
*/
// self-sign certificate
cert.sign(keys.privateKey);

console.log(pki.certificateToPem(cert));
var verified = keys.publicKey.verify(cert);
console.log('Verification of cert: '+verified);
lbcsultan commented 6 years ago

F:\AppliedCrypto\forge>node cert.js -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgIBATANBgkqhkiG9w0BAQUFADBpMRQwEgYDVQQDEwtleGFt cGxlLm9yZzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCFZpcmdpbmlhMRMwEQYDVQQH EwpCbGFja3NidXJnMQ0wCwYDVQQKEwRUZXN0MQ0wCwYDVQQLEwRUZXN0MB4XDTE3 MTExMzA1MzY0MloXDTE4MTExMzA1MzY0MlowaTEUMBIGA1UEAxMLZXhhbXBsZS5v cmcxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxh Y2tzYnVyZzENMAsGA1UEChMEVGVzdDENMAsGA1UECxMEVGVzdDCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAIANEkQak5Ehc6IDn7gXj5VhkBBhvELncFoy Hml8DVllgpPXuJY/yAv0AazYoC22hzV2w1f+Ma25rygbo9ooz298XCvEcNybJFgI 20h76TOGA5t7MXY7pn5U2fCNy4Fa8770bD8CuiFM30bZ+kvesfELCCzfOxW/ozLe r1OFM6nrGR2WzO03rK7QX7iMo4486mMHdmbNnoJZCVBTzjXwgW82llvFqBZwwcDV Yb7MNVYNWb8FC0JhjyW85tYXmZwzNECbDg6Gg+4+G6e8Tg1c60AQSRPjLR3olu65 YZb3hljnEaVNmj+aCAId2j32TSilHf8yYfiDMedm1raPRm2NILkCAwEAAaOBuzCB uDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIC9DA7BgNVHSUENDAyBggrBgEFBQcD AQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwgwEQYJYIZI AYb4QgEBBAQDAgD3MCwGA1UdEQQlMCOGG2h0dHA6Ly9leGFtcGxlLm9yZy93ZWJp ZCNtZYcEfwAAATAdBgNVHQ4EFgQUdB+mILe1p21DzYKqier+QTHH31kwDQYJKoZI hvcNAQEFBQADggEBAHM0Zn0ariJDFAtCJclo6Csi0aZavc5M8vTm4T0dISdFBjz9 0nN4BDWVz+UoQ6giaHjrYCeRvQNOsMO79RTdD4CoePb7aMt2QpSR4fwt5CXDiFSe 0+EFn2tcUkNhm5jMapCtDmG9keubkesLHI8DKtMX8Rj9tOYOnaFxIfKv1TXr8CSm R8Y1seb7NNEsPNY4kPqG7negiBoH1yrTgNJCG8jgJXgAuNaOvOZ7hLDb3vD9uytQ ySQvj+K6IhA86C5/hV8apW9y6g+WF5wIwMopRyG2PhFglpxesW8Sjo34c9wfkpxz kUwGS1hei2iuLRmoa4PhKJH58wbYIXdX3WHQsWw= -----END CERTIFICATE-----

F:\AppliedCrypto\forge\node_modules\node-forge\lib\rsa.js:535 if(ed.length !== k) { ^

TypeError: Cannot read property 'length' of undefined at Object.pki.rsa.decrypt (F:\AppliedCrypto\forge\node_modules\node-forge\lib\rsa.js:535:8) at Object.key.verify (F:\AppliedCrypto\forge\node_modules\node-forge\lib\rsa.js:1076:22) at Object. (F:\AppliedCrypto\forge\cert.js:95:31) at Module._compile (module.js:569:30) at Object.Module._extensions..js (module.js:580:10) at Module.load (module.js:503:32) at tryModuleLoad (module.js:466:12) at Function.Module._load (module.js:458:3) at Function.Module.runMain (module.js:605:10) at startup (bootstrap_node.js:158:16)

mkg20001 commented 6 years ago

You tried to verify the certificate using the public key which expects data and a signature. Instead, try cert.verify(cert)

lbcsultan commented 6 years ago

Thanks mgk20001. It works well. I think the API document should be described more clearly on this.

pke commented 3 years ago

@lbcsultan @mkg20001 so what is the solution to this? How to verify the certificate was signed with a particular private key? cert.verify(cert) requires to create a new signed certificate just to verify its public key?

I am using this at the moment but would hope to rely more on library functions:

expect(cert.pem.publicKey.n).toEqual(privateKey.n)
expect(cert.pem.publicKey.e).toEqual(privateKey.e)
lbcsultan commented 3 years ago

To verify the validity of a certificate (cert) that was signed by a CA, you have to use CA's certificate (caCert). CA's public key is included in CA's certificate. The API of verify() method is cert.verify(caCert)

pke commented 3 years ago

I want to verify the public key of a self signed cert and find out if it was signed by the private key in question. No CA involved in my (S/MIME) scenario

jay-stance commented 2 years ago

But please how do I sign a certificate using a CA in node-forge