使用JWTSigner.sign()生成的令牌,在jwt.io调试器

时间:2016-10-27 22:57:09

标签: java jwt

我们使用java-jwt编写了小型API。当我创建一个令牌并在Java代码中验证令牌时,它工作正常。

  1. 创建了RSA私钥和公钥。 (参考其中一个测试用例)
  2. 使用带有私钥的Algorithm.RS256创建一个令牌。
  3. 验证了相同的令牌,并按预期获得了输出。
  4. 然后将公钥提供给客户端,我们开始使用生成的令牌调用其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());
    }
    

    创建令牌

    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);
    }
    

    验证令牌

    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;
    }
    

    输入

    iccid:4454788545885968585##
    nonce:5e452610c9f9decd:-404fb717:157fd6fc54e:-7ffe##
    timestamp:2016-10-25T16:16:36.036Z
    

    创建令牌输出

      

    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
    

    公钥

    -----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-----
    

1 个答案:

答案 0 :(得分:5)

似乎jwt.io需要公钥文件(PKCS#8):

-----BEGIN PUBLIC KEY-----
BASE64 DATA
-----END PUBLIC KEY-----

而不是您传递的RSA公钥文件(PKCS#1):

-----BEGIN RSA PUBLIC KEY-----
BASE64 DATA
-----END RSA PUBLIC KEY-----

有趣的是,如果您手动编辑文件以仅用RSA PUBLIC KEY标记替换PUBLIC KEY标记,那么您将获得经过验证的签名。这很奇怪,因为BASE64数据根据格式会有所不同,但是,我没有查看细节,以了解如果有任何罪魁祸首,所以不要问我为什么,但是会工作的。