我们用java-jwt编写了小API .当我创建一个令牌并在Java代码中验证令牌时,它工作正常.
然后向客户端提供公钥,我们开始使用生成的令牌调用其REST服务.客户端使用https://www.npmjs.com/package/jsonwebtoken验证令牌.他们回来说,令牌和公钥提供了jwt.io调试器中的无效签名.他们要求首先在jwt.io调试器中使其工作.我不明白什么时候它在Java代码中使用相同的公共为什么它在jwt.io中这样说.我错过了什么吗?
public void createPemFiles(String absoluteFilePath) throws Exception {
logger.log(Level.INFO, "Received request to create Key pair : " + absoluteFilePath);
PemWriter pemWriter = new PemWriter();
// create key pair
final KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");
generator.initialize(KEY_SIZE);
final KeyPair keyPair = generator.generateKeyPair();
// write private key
final RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
privateKeyPem = new File(absoluteFilePath);
pemWriter.writePrivateKey(privateKey, "RSA PRIVATE KEY", privateKeyPem.getAbsolutePath());
logger.log(Level.INFO, "Created private key : " + privateKeyPem.getAbsolutePath());
// write public key
publicKeyPem = new File(absoluteFilePath+".pub");
final RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
pemWriter.writePublicKey(publicKey, "RSA PUBLIC KEY", publicKeyPem.getAbsolutePath());
logger.log(Level.INFO, "Created public key : " + publicKeyPem.getAbsolutePath());
}
Run Code Online (Sandbox Code Playgroud)
public String createJWTToken(String [] keyValues) {
final HashMap<String, Object> claims = new HashMap<String, Object>();
String [] nameValue;
for(String keyValue : keyValues) {
nameValue = keyValue.split("##");
claims.put(nameValue[0],nameValue[1]);
}
return JWTSIGNER.sign(claims, OPTIONS);
}
Run Code Online (Sandbox Code Playgroud)
public String verifyJWTToken(String token) throws Exception{
logger.log(Level.DEBUG, "Received request for verify JWT token");
Map<String, Object> claims = JWTVERIFIER.verify(token);
String claimString = "";
String key = "";
String value = "";
for(Map.Entry<String, Object> entry : claims.entrySet()) {
key = entry.getKey();
value = (String) entry.getValue().toString();
claimString = claimString + key +":"+ value + "##";
}
claimString = replaceLast(claimString, "##", "");
logger.log(Level.DEBUG, "Successfully verified : "+claimString);
return claimString;
}
Run Code Online (Sandbox Code Playgroud)
输入
iccid:4454788545885968585##
nonce:5e452610c9f9decd:-404fb717:157fd6fc54e:-7ffe##
timestamp:2016-10-25T16:16:36.036Z
Run Code Online (Sandbox Code Playgroud)
创建令牌输出
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpY2NpZCI6IjQ0NTQ3ODg1NDU4ODU5Njg1ODUiLCJub25jZSI6IjVlNDUyNjEwYzlmOWRlY2Q6LTQwNGZiNzE3OjE1N2ZkNmZjNTRlOi03ZmZlIiwidGltZXN0YW1wIjoiMjAxNi0xMC0yNVQxNjoxNjozNi4wMzZaIn0.PlWVn1jlkvjRpw34-fsjJGQVVd74sFdg7SS2UgA4HUx4vBMYMA4b-Zzg5VxyzYkhzSsQqjKn7UBw04fXIwsmaP9A7Pc3-MjHjbmYT3Yv52qvH4yNy6X_M0z41UHuuLaWVQN3eck5BKIoO2cy4ihb8OOISkzF1Cf-Udx1GB-bVY4C4JtIvGpMflVW4hS9ZpWzKz26qlva7Y9KMEmvW24tviNcy8aVNyC55MS_KS_Ab7YWQ-MERRiNTCDIqUG7YVSN2Ap_SsNMab687GknQh78ibAowUdpLbGRU4N5EHZyG2lg-u-oL594fRA2anr-JunSxtpkI8-tKzR9NG5dt4F79Q
验证令牌输出
iccid:4454788545885968585##
nonce:5e452610c9f9decd:-404fb717:157fd6fc54e:-7ffe##
timestamp:2016-10-25T16:16:36.036Z
Run Code Online (Sandbox Code Playgroud)
公钥
-----BEGIN RSA PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx58WGD/wRFnwe64sl/9V
KuNOQChYUy8GfhQU66M2XSnx/UpjPCqhGYRmpUXT+rQAamUDsarGt8Kbw1DtlvLT
p2UTvSWiCJNQzi53CRa6iDbk213Ps7zuAFhuXB7s0ZqdOZbeJnXFFM/wMJbM6kdB
yAdCwj8/kCKCjSt3Q0CLdxaToTucRJuO7/V4wbJIDMfLt3LPlry/PsHQAx0RKXco
TO1JsSGWg99dHBEqpxLMBtZyhyd8++PrMrtQ4pPVAmXoJODKY2NZkiLl3h4Ai48z
FhBNHsWQDTJKA8skb2JQER9i1a1/ip/cgkR6FG6G65DbhrMElcL0mgdst49PF26p
pwIDAQAB
-----END RSA PUBLIC KEY-----
Run Code Online (Sandbox Code Playgroud)
似乎jwt.io需要一个公钥文件(PKCS#8):
-----BEGIN PUBLIC KEY-----
BASE64 DATA
-----END PUBLIC KEY-----
Run Code Online (Sandbox Code Playgroud)
而不是您传递的RSA公钥文件(PKCS#1):
-----BEGIN RSA PUBLIC KEY-----
BASE64 DATA
-----END RSA PUBLIC KEY-----
Run Code Online (Sandbox Code Playgroud)
有趣的是,如果您手动编辑文件以RSA PUBLIC KEY仅用PUBLIC KEY标记替换标记,那么您将获得经过验证的签名.这很奇怪,因为BASE64数据根据格式会有所不同,但是,我没有查看详细信息,以了解如果有任何罪魁祸首所以不要问我为什么,但这样可行.