2016-10-20 2 views
0

J'ai besoin de votre aide encore une fois ...signature en Java avec la clé publique existante pour JWT

Je veux accéder à l'API Box et autoriser l'aide d'un JWT JSON (Token Web). Pour ce faire, je dois créer un Assertion.
« Chaque assertion JWT se compose de trois éléments, l'en-tête, les revendications, et la signature
- L'en-tête spécifie l'algorithme utilisé pour la
signature JWT . - Les revendications contiennent les informations nécessaires pour s'authentifier et fournir le jeton correct
- La signature est utilisée pour vérifier l'identification de l'application et est vérifiée à l'aide de la clé publique

Une fois encodée et concaténée, l'assertion JWT sera vérifiée. comme ceci: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9eyJpc3MiOiJ2Z3 B2bWFvaDJjZ2ZjNGRuMzFnMWx0cmlhbmdlZCIsInN1YiI 6IjE2ODczOTQzIiwiZXhwIjoxNDI5MDM3ODYwLCJqdGkiOiJ »

Ainsi, une paire de clés RSA je devais créer avant et a dû déposer la clé publique dans la boîte devolper application.

Maintenant, je ne sais pas comment créer la signature. J'ai trouvé une solution avec la création du Keypair, mais comme je l'ai déjà, je ne sais pas comment modifier le code.

import java.security.KeyPair; 
import java.security.KeyPairGenerator; 
import java.security.Signature; 

import sun.misc.BASE64Encoder; 

public class MainClass { 
    public static void main(String[] args) throws Exception { 
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
    kpg.initialize(1024); 
    KeyPair keyPair = kpg.genKeyPair(); 

    byte[] data = "test".getBytes("UTF8"); 

    Signature sig = Signature.getInstance("MD5WithRSA"); 
    sig.initSign(keyPair.getPrivate()); 
    sig.update(data); 
    byte[] signatureBytes = sig.sign(); 
    System.out.println("Singature:" + new 
      BASE64Encoder().encode(signatureBytes)); 

    sig.initVerify(keyPair.getPublic()); 
    sig.update(data); 

    System.out.println(sig.verify(signatureBytes)); 
    } 
} 
+1

Avez-vous envisagé d'utiliser le [Java SDK for Box] officiel (https://github.com/box/box-java-sdk)? Il va gérer le flux d'authentification JWT pour vous. Si vous voulez l'écrire vous-même, vous pouvez consulter leur [implémentation JWT] (https://github.com/box/box-java-sdk/blob/master/src/main/java/com/box/sdk/ BoxDeveloperEditionAPIConnection.java) pour l'inspiration. –

+0

Une fois que vous avez généré votre paire de clés, vous devez la stocker d'une manière ou d'une autre. Un fichier PEM pour la clé publique et un pour la clé privée est un moyen courant de le stocker. Cependant, quand j'ai essayé de configurer un code similaire au vôtre il y a quelques semaines, j'ai fini par passer de MD5 avec RSA à HMAC-SHA256 parce que le processus de lecture d'un fichier PEM sur un Java KeyPari était tellement fastidieux! –

Répondre

0

Box Api dit

RSA doit être keypair au format PEM

Donc, vous devez exporter votre clé publique à PEM. Utilisez ce code (java8)

public static String exportPublicKeyAsPem(PublicKey publicKey) throws Exception { 
    StringWriter sw = new StringWriter(); 

    sw.write("-----BEGIN PUBLIC KEY-----\n"); 
    sw.write(Base64.getEncoder().encodeToString(publicKey.getEncoded())); 
    sw.write("\n-----END PUBLIC KEY-----\n"); 

    return sw.toString(); 
} 

Création d'un jeton JWT signé peut être fait de cette manière (Vous pouvez également utiliser une bibliothèque)

public static String signJWT (String header, String payload, PrivateKey privateKey) throws Exception{ 
    String token = 
      Base64.getUrlEncoder().encodeToString(header.getBytes()) 
      + "." 
      +Base64.getUrlEncoder().encodeToString(payload.getBytes()); 

    Signature sig = Signature.getInstance("SHA256WithRSA"); 
    sig.initSign(privateKey); 
    sig.update(token.getBytes()); 
    byte[] signature = sig.sign(); 

    return token + "." + Base64.getUrlEncoder().encodeToString(signature); 
} 

En utilisant le code:

public final static void main(String argv[]) throws Exception{ 

    String header = "{\"alg\": \"RS256\",\"typ\": \"JWT\"}"; 
    String payload = "{\"sub\": \"1234567890\",\"name\": \"John Doe\"}"; 

    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
    kpg.initialize(1024); 
    KeyPair keyPair = kpg.genKeyPair(); 

    String publicKeyPem = exportPublicKeyAsPem(keyPair.getPublic()); 
    String signedToken = signJWT (header, payload, keyPair.getPrivate()); 

    System.out.println(publicKeyPem); 
    System.out.println(signedToken); 
} 

Enfin, vous devrez stocker la paire de clés et la charger avant de l'utiliser. Je vous recommande de pré-générer la paire de clés en utilisant openssl comme BoxApi documentation says