如何从 X509 证书中提取 AuthorityKeyIdentifier

How to extract AuthorityKeyIdentifier from X509 Certificate

我正在尝试使用 scala 中的 bouncycastle 从有效证书中提取 AuthorityKeyIdentifier (OID:2.5.29.35)。

case class ExtendedX509Certificate(x509Certificate : X509Certificate) {
  
  object OID {
    val SUBJECT_KEY_IDENTIFIER : String = "2.5.29.14"
    val AUTHORITY_KEY_IDENTIFIER : String = "2.5.29.35"
  }

我想出了 SubjectKeyIdentifier 的方法:

  def getSubjectKeyIdentifier : SubjectKeyIdentifier = {
      val encoding : Array[Byte] = x509Certificate.getExtensionValue(OID.SUBJECT_KEY_IDENTIFIER)
      SubjectKeyIdentifier.getInstance(encoding)
  }

但是,AuthorityKeyIdentifier 的类似代码不起作用:

  def getAuthorityKeyIdentifier : AuthorityKeyIdentifier = {
      val encoding : Array[Byte] =   x509Certificate.getExtensionValue(OID.AUTHORITY_KEY_IDENTIFIER)
      AuthorityKeyIdentifier.getInstance(encoding)
  }
}

并崩溃:

java.lang.IllegalArgumentException: unknown object in getInstance: org.bouncycastle.asn1.DEROctetString

为什么相同的方法对这两个标识符不起作用,我该如何使它起作用?

我正在测试使用:

MIIJcDCCCFigAwIBAgIRAJw0GpsHpPOHAwAAAADLz1cwDQYJKoZIhvcNAQELBQAwQjELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczETMBEGA1UEAxMKR1RTIENBIDFPMTAeFw0yMTAzMTYxOTI4MDdaFw0yMTA2MDgxOTI4MDZaMGYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgTExDMRUwEwYDVQQDDAwqLmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAStiyrIqG9oMic5xVjELBgdysk+PFeTkM0NITAegkbaq3UQe8kNBcISg8e1oYZK3IPsiTXkJOzVK/EH8hITU7GYo4IHBjCCBwIwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFDZSim5o0oHdHYbMsDYIHyyJt62bMB8GA1UdIwQYMBaAFJjR+G4Q68+b7GCfGJAboOt9Cf0rMGgGCCsGAQUFBwEBBFwwWjArBggrBgEFBQcwAYYfaHR0cDovL29jc3AucGtpLmdvb2cvZ3RzMW8xY29yZTArBggrBgEFBQcwAoYfaHR0cDovL3BraS5nb29nL2dzcjIvR1RTMU8xLmNydDCCBMIGA1UdEQSCBLkwggS1ggwqLmdvb2dsZS5jb22CDSouYW5kcm9pZC5jb22CFiouYXBwZW5naW5lLmdvb2dsZS5jb22CCSouYmRuLmRldoISKi5jbG91ZC5nb29nbGUuY29tghgqLmNyb3dkc291cmNlLmdvb2dsZS5jb22CGCouZGF0YWNvbXB1dGUuZ29vZ2xlLmNvbYITKi5mbGFzaC5hbmRyb2lkLmNvbYIGKi5nLmNvgg4qLmdjcC5ndnQyLmNvbYIRKi5nY3BjZG4uZ3Z0MS5jb22CCiouZ2dwaHQuY26CDiouZ2tlY25hcHBzLmNughYqLmdvb2dsZS1hbmFseXRpY3MuY29tggsqLmdvb2dsZS5jYYILKi5nb29nbGUuY2yCDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qcIIOKi5nb29nbGUuY28udWuCDyouZ29vZ2xlLmNvbS5hcoIPKi5nb29nbGUuY29tLmF1gg8qLmdvb2dsZS5jb20uYnKCDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20udHKCDyouZ29vZ2xlLmNvbS52boILKi5nb29nbGUuZGWCCyouZ29vZ2xlLmVzggsqLmdvb2dsZS5mcoILKi5nb29nbGUuaHWCCyouZ29vZ2xlLml0ggsqLmdvb2dsZS5ubIILKi5nb29nbGUucGyCCyouZ29vZ2xlLnB0ghIqLmdvb2dsZWFkYXBpcy5jb22CDyouZ29vZ2xlYXBpcy5jboIRKi5nb29nbGVjbmFwcHMuY26CFCouZ29vZ2xlY29tbWVyY2UuY29tghEqLmdvb2dsZXZpZGVvLmNvbYIMKi5nc3RhdGljLmNugg0qLmdzdGF0aWMuY29tghIqLmdzdGF0aWNjbmFwcHMuY26CCiouZ3Z0MS5jb22CCiouZ3Z0Mi5jb22CFCoubWV0cmljLmdzdGF0aWMuY29tggwqLnVyY2hpbi5jb22CECoudXJsLmdvb2dsZS5jb22CFioueW91dHViZS1ub2Nvb2tpZS5jb22CDSoueW91dHViZS5jb22CFioueW91dHViZWVkdWNhdGlvbi5jb22CESoueW91dHViZWtpZHMuY29tggcqLnl0LmJlggsqLnl0aW1nLmNvbYIaYW5kcm9pZC5jbGllbnRzLmdvb2dsZS5jb22CC2FuZHJvaWQuY29tghtkZXZlbG9wZXIuYW5kcm9pZC5nb29nbGUuY26CHGRldmVsb3BlcnMuYW5kcm9pZC5nb29nbGUuY26CBGcuY2+CCGdncGh0LmNuggxna2VjbmFwcHMuY26CBmdvby5nbIIUZ29vZ2xlLWFuYWx5dGljcy5jb22CCmdvb2dsZS5jb22CD2dvb2dsZWNuYXBwcy5jboISZ29vZ2xlY29tbWVyY2UuY29tghhzb3VyY2UuYW5kcm9pZC5nb29nbGUuY26CCnVyY2hpbi5jb22CCnd3dy5nb28uZ2yCCHlvdXR1LmJlggt5b3V0dWJlLmNvbYIUeW91dHViZWVkdWNhdGlvbi5jb22CD3lvdXR1YmVraWRzLmNvbYIFeXQuYmUwIQYDVR0gBBowGDAIBgZngQwBAgIwDAYKKwYBBAHWeQIFAzAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLnBraS5nb29nL0dUUzFPMWNvcmUuY3JsMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYARJRlLrDuzq/EQAfYqP4owNrmgr7YyzG1P9MzlrW2gagAAAF4PLlsagAABAMARzBFAiEApRqC2iz6Cbaeb4jbldMuo7SKM17Ny5cBNBgf+BCK4bgCIFkPEsjRsVhOmHj9Nn9rB1yL+/B09nkTWLuha+RHZIZSAHUA9lyUL9F3MCIUVBgIMJRWjuNNExkzv98MLyALzE7xZOMAAAF4PLlsZgAABAMARjBEAiAj9/hBHDtUKPzf/rfAvUtsYNUYgJip1ji6033vWQ/jrQIgcop8+lortNPmu2CCKKxw4BGZW1knDLAMxrGp4PJquZEwDQYJKoZIhvcNAQELBQADggEBAE5+iUBlgC5S1ji+aR1vODHbrTzwxZdPc0v/R2R7Pw+/HCRcGx5VrAReKXte/P41x19vRywiLY0leiKUIbOLU5BPU1mJbl4aPSWEIJZbGG2e1655MXKM+O3VvNZDPLCyIULB5rRnu/8Fi1b5YHxiBbzcGNCGLUPXWiG8LkFwxJ//VcWVDMxbfbNP9Tloumged41hsBabAZCO/0KzpmcIjY70fo8xSq5//W0KyxEI5FDt7+pqPnkCyiGzCU4nqe1GzThvxi/zM4GRLW/h5cDSwpjM/RifH1KIHb5nmg8QDaNJwUtUK/KyM478MNWfQ32VixeljVRiwA+QOybuk+B877I=

我使用以下方法解析该文件:

def fromPEMString(cert: String, addWrapperLines: Boolean = false): Option[ExtendedX509Certificate] = {
    val PEMString = {
      if (addWrapperLines) {
        val startLine = "-----BEGIN CERTIFICATE-----"
        val endLine = "-----END CERTIFICATE-----"
        s"$startLine\n$cert\n$endLine"
      } else {
        cert
      }

    }
    Option(X509CertUtils.parse(PEMString)) match {
      case Some(parsed) => Some(ExtendedX509Certificate(cert, parsed))
      case None => None
    }
  }

好的,我想我发现了错误。

AuthorityKeyIdentifier.getInstance(encoding)

您应该传递一个按 ASN.1 八位字节字符串排列的字节数组。因此,一种方法可以是:

AuthorityKeyIdentifier.getInstance(ASN1OctetString.getInstance(encoding).getOctets)

希望对你有所帮助。