2017-08-11 80 views
1

我生成了JKS格式的RSA 256公钥/私钥。从JKS导出公钥并从Java中读取

keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 10950 

该文件在Keycloak中配置,该文件将使用私钥签名访问令牌(JWT)。

从我的基于Java的应用程序中,我想用公钥来验证访问令牌的签名。可能存在一个更简单的机制,但尝试各种方法后我感到困惑。从JKS文件

keytool -export -alias selfsigned -keystore keystore.jks -rfc -file publickey.cert 

导出的公钥证书来从Java应用程序的证书文件:

// Use file stream to load from file system or class.getResourceAsStream to load from classpath    
InputStream readStream = this.getClass().getClassLoader().getResourceAsStream("publickey.cert"); 

CertificateFactory f = CertificateFactory.getInstance("X.509"); 

//Certificate certificate = f.generateCertificate(readStream); 
X509Certificate certificate = (X509Certificate)f.generateCertificate(readStream); 

publicKey = certificate.getPublicKey(); 

readStream.close(); 

验证签名用的公钥和jjwt

Jwts.parser().setSigningKey(publicKey).parseClaimsJws(accessToken).getBody(); 

以上代码会抛出此异常:

io.jsonwebtoken.SignatureException: Unable to verify RSA signature using configured PublicKey. Signature length not correct: got 256 but was expecting 1369 

我在做对吧?

+0

你不应该需要输出什么。数字签名应包括签名人的证书,并包括其公钥。 – EJP

+0

@EJP我不相信签名者。所以,我必须确保它确实使用了相同的密钥我签名 –

+0

不,您必须确保*完整的证书*是相同的,并且是可信的。在那之后,从哪里获取公钥并不重要。 – EJP

回答

0

这是我的错误,我试图用错误的证书(Keycloak JBOSS)验证签名,但实际上访问令牌是使用Realm的密钥签名的。我必须从领域 - >密钥 - > RSA - >证书(不是通过在Keycloak Jboss配置的密钥库JKS中生成证书文件)创建证书文件。

0

它应该工作,我试着生成相同的一组密钥/证书并验证它(我用的充气城堡)

import org.bouncycastle.jce.provider.BouncyCastleProvider; 
import org.bouncycastle.jce.provider.X509CertificateObject; 
import org.bouncycastle.util.io.pem.PemObject; 
import org.bouncycastle.util.io.pem.PemReader; 

import java.io.*; 
import java.security.KeyStore; 
import java.security.Security; 
import java.security.cert.CertificateFactory; 
import java.security.cert.X509Certificate; 
import java.util.Enumeration; 
public class CertTest { 
    public static void main(String[] args) throws Exception { 
    Security.addProvider(new BouncyCastleProvider()); 
    KeyStore ks = KeyStore.getInstance("JKS"); 
    try (Reader readStream = new FileReader("publickey.cert")){ 
     PemReader reader = new PemReader(readStream); 
     CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); 
     PemObject pemObject = reader.readPemObject(); 
     X509Certificate cert = (X509Certificate)certFactory.generateCertificate(new ByteArrayInputStream(pemObject.getContent())); 
     System.out.println(cert.getPublicKey().getAlgorithm()); 
    } 
    } 
} 

打印:RSA

+0

是的,它应该工作。请看我的答案。不管怎么说,还是要谢谢你! –