【问题标题】:Sign a JWT with a SHA cert using jose4j使用 jose4j 使用 SHA 证书签署 JWT
【发布时间】:2015-12-04 20:40:10
【问题描述】:

初次使用 jose4j。我找到了这样的例子来从证书设置私钥:

JsonWebSignature jws = new JsonWebSignature();
PKCS8EncodedKeySpec spec =
new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey pk = kf.generatePrivate(spec);
jws.setKey(kf.generatePrivate(spec));

但我收到此错误消息

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format    

我认为这是因为证书是作为 SHA256 而不是 RSA 创建的。这是我被告知创建证书的方式:

openssl req -x509 -sha256 -nodes -days 730 -newkey rsa:2048 -keyout private.key -out certificate_pub.crt

有没有人可以举例说明如何使用 SHA256 证书签署 JWT?

【问题讨论】:

  • 证书 使用 SHA256 RSA 进行签名,但您用于签名的 私钥 确实如此不使用任何散列,只是 RSA。 (如果它被加密,PBE 将包含一些散列,但这是不可选的。)对于最近的版本(1.0.0 及更高版本)大多数openssl 命令行操作,包括这个,在 PKCS 中写入私钥PEM 中的#8 格式。文件的第一行可读字符-----BEGIN PRIVATE KEY-----吗?您(或任何人)是否使用 1.0.0+ 并且在将 PEM 放入 PKCS8EncodedKeySpec 之前是否将 PEM 转换为二进制
  • 证书文件是可读的,并且以 -----BEGIN RSA PRIVATE KEY-----.... 我也尝试从文件并运行,但它没有帮助。下面是我用来读取私钥文件的代码:String filename = "C:\\private.key";文件 f = 新文件(文件名); FileInputStream fis = new FileInputStream(f); DataInputStream dis = new DataInputStream(fis); byte[] keyBytes = new byte[(int)f.length()]; dis.readFully(keyBytes);

标签: certificate jwt private-key sha


【解决方案1】:

使用附加信息,该私钥文件是 PEM 但不是 PKCS#8,因为现代版本的 OpenSSL 应该为 req -newkey 创建。标准 Java 要求的 PEM 和“DER”(二进制)之间的区别不仅仅是删除(和添加)BEGIN 和 END 行。

如果 OpenSSL 可用,您最简单的解决方案是在不加密的情况下转换两者

openssl pkcs8 -topk8 -nocrypt -outform der -in private.pem -out good.der 

然后将good.der(如果您愿意,可以使用更好的名称)读取为字节,并将其放入PKCS8EncodedKeySpec 并在您发布时使用它。另外:您不需要摆弄DataInputStream,它并不是真正用于“普通旧”字节的; java.nio.file.Files.readAllBytes可以为你打开、分配、读取。

下一个更复杂的替代方法是转换为 PKCS#8 但仍为 PEM:与 about 相同但省略 -outform der(并使用指示 PEM 的文件名,以避免混淆)。然后在 Java 中将 那个 文件读取为 characters(使用 Reader,通常是 BufferedReader,而不是 Stream),丢弃 BEGINEND行,连接之间的所有行,并将它们从base64转换为byte[]:在Java8中你有java.util.Base64,在此之前你可以使用javax.xml.bind.DatatypeConverter

阅读标准 Java 中的文件比较困难。您可以读取 PEM 装甲 PKCS#1 并转换为二进制 PKCS#1,然后通过构建 DER 编码将 PKCS#1“包装”到 PKCS#8,但这比您所展示的熟悉程度要复杂得多和。或者您可以解析 PKCS#1 并使用这些组件来构建您自己的 RSAPrivateCrtKey 实现并直接使用它(无工厂),同上。

另一种选择是使用来自http://www.BouncyCastle.org 的第三方库,它在处理 PEM 文件方面比标准 Java 具有更灵活的功能。但是您需要了解他们的 API 以及标准 API,如果您的程序可以在其他任何地方运行,您需要确保 BC 与您的程序一起部署或作为程序的一部分进行部署。

【讨论】:

    猜你喜欢
    • 2017-12-24
    • 2018-12-02
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多