2015-10-17 1 views
2

Je travaille sur un protocole sécurisé client-serveur où j'ai besoin d'utiliser RSA en Java pour crypter une clé secrète pour les condensats HMAC car la clé doit être envoyée au serveur. Le cryptage a deux étapes; Premièrement, j'ai besoin de crypter la clé symétrique avec une clé asymétrique publique, puis, ce message crypté est crypté avec une clé asymétrique privée.Cryptage d'une clé secrète avec RSA en Java

A cet effet, je produis le SecretKey comme:

public SecretKey generate(){ 
KeyGenerator generator = KeyGenerator.getInstance("HMACSHA256"); 
k = generator.generateKey(); 
return k; 
} 

Plus tard, j'utiliser ce code pour chiffrer tout tableau d'octets avec une clé publique:

public byte[] encryptPublic(PublicKey key, byte[] array){ 
Cipher cipher = Cipher.getInstance("RSA"); 
cipher.init(Cipher.ENCRYPT_MODE, key); 
byte[] encrypted = cipher.doFinal(array); 
return encrypted; 
} 

Le code pour le chiffrement avec un privé La clé est la même mais en utilisant une clé privée.

Pour le cryptage RSA J'utilise 1024 bits longues clés asymétriques et j'ai donc deux questions principales:

  1. Comment puis-je transformer mon SecretKey à un tableau d'octets afin de le chiffrer avec RSA et public clé?
  2. Étant donné que le chiffrement par clé publique produit un tableau d'octets de 128 octets, comment puis-je chiffrer à nouveau ce message avec une clé privée si la clé est longue de 1024 bits et ne peut chiffrer qu'un message long de 117 octets?
+2

Quelques commentaires. 1) Ne pas utiliser les valeurs par défaut dans la cryptographie, n'importe où. Dans votre méthode 'getInstance()', spécifiez toujours la chaîne de transformation complète en trois parties. 2). Ne cryptez pas avec la clé privée, exécutez plutôt * signing *. Vous utilisez la classe 'Signature' pour cela. 3) Les clés, y compris SecretKeys, ont la méthode 'getEncoded()' pour retourner un tableau d'octets représentant la clé dans un format standard. Pour les clés symétriques, c'est-à-dire les instances 'SecretKey', le tableau d'octets renvoyé par' getEncoded() 'est simplement la clé brute octets. –

+0

Pour Q2: Vous pouvez crypter le texte chiffré avec une clé AES aléatoire, puis crypter cette nouvelle clé AES avec un autre tour de RSA, mais pourquoi voudriez-vous le faire? –

Répondre

2
  1. Comment puis-je transformer mon SecretKey à un tableau d'octets afin de le chiffrer avec RSA et une clé publique?

Ce qu'on appelle l'emballage:

public static byte[] wrapKey(PublicKey pubKey, SecretKey symKey) 
     throws InvalidKeyException, IllegalBlockSizeException { 
    try { 
     final Cipher cipher = Cipher 
       .getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding"); 
     cipher.init(Cipher.WRAP_MODE, pubKey); 
     final byte[] wrapped = cipher.wrap(symKey); 
     return wrapped; 
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { 
     throw new IllegalStateException(
       "Java runtime does not support RSA/ECB/OAEPWithSHA1AndMGF1Padding", 
       e); 
    } 
} 

Notez que cela ne convertit pas explicitement à byte[] premier. C'est parce que la clé pourrait bien être dans e.g. un module de sécurité matériel. Dans un HSM, l'encapsulation peut être possible, mais la conversion vers byte[] dans la mémoire locale n'est généralement pas possible.


  1. Comme le chiffrement à clé publique produit un tableau d'octets avec 128 octets, comment puis-je chiffrer ce message à nouveau avec une clé privée si la clé est de 1024 bits de long et ne peut crypter un message long de 117 octets?

Vous ne devriez pas faire cela et vous ne pouvez pas faire cela non plus. La raison pour laquelle vous ne devriez pas le faire parce que le cryptage avec la clé privée ne fournit pas la confidentialité, comme n'importe qui aurait accès à la clé publique.

Un remplissage est requis pour effectuer un cryptage RSA sécurisé. La surcharge de remplissage (de 11 octets pour le remplissage de style PKCS # 1 v1.5) vous interdit de crypter avec la clé privée.

Notez que toute l'opération: cryptage avec une clé privée n'est même pas spécifiée dans PKCS # 1 - ce n'est pas une opération légitime.


Habituellement, le (CE) beaucoup plus sûre éphémère éphémère DH est utilisé pour établir des clés dans les protocoles de transport, en utilisant la clé privée (s) que pour l'authentification. Vous pouvez prendre un indice à partir des (versions brouillon de) TLS 1.3.Ou vous pouvez juste vouloir utiliser TLS ou la partie handshake de celui-ci.