2010-04-14 2 views
5

*** sweet - merci à Edward Smith pour la note technique des FC qui indiquait que la clé de ColdFusion était encodée en Base64. Voir generateKey() pour le 'fix'Comment faire correspondre le chiffrement ColdFusion avec Java 1.4.2?

Ma tâche consiste à utiliser Java 1.4.2 pour faire correspondre les résultats d'un exemple de code ColdFusion donné pour le chiffrement.

connus/valeurs données:

  • A 24 octets clé
  • A
  • encodage est Hex
  • algorithme de cryptage sel de 16 octets (IVorSalt) est AES/CBC/PKCS5Padding
  • Exemple de valeur de texte en clair
  • La valeur chiffrée de l'échantillon après avoir passé le code ColdFusion

Hypothèses:

  • Nombre d'itérations non spécifiées dans le code ColdFusion donc je suppose qu'une seule itération
  • 24 octets clé donc je suppose que le cryptage

192-bit données/exemple de code de chiffrement ColdFusion de travail:

<cfset ThisSalt = "16byte-salt-here"> 
<cfset ThisAlgorithm = "AES/CBC/PKCS5Padding"> 
<cfset ThisKey = "a-24byte-key-string-here"> 
<cfset thisAdjustedNow = now()> 
<cfset ThisDateTimeVar = DateFormat(thisAdjustedNow , "yyyymmdd")> 
<cfset ThisDateTimeVar = ThisDateTimeVar & TimeFormat(thisAdjustedNow , "HHmmss")> 
<cfset ThisTAID = ThisDateTimeVar & "|" & someOtherData> 
<cfset ThisTAIDEnc = Encrypt(ThisTAID , ThisKey , ThisAlgorithm , "Hex" , ThisSalt)> 

Mon Java 1.4.2 chiffrement/déchiffrement du code butin:

package so.example; 

import java.security.*; 
import javax.crypto.Cipher; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 
import org.apache.commons.codec.binary.*; 

public class SO_AES192 { 

private static final String _AES = "AES"; 
private static final String _AES_CBC_PKCS5Padding = "AES/CBC/PKCS5Padding"; 
private static final String KEY_VALUE = "a-24byte-key-string-here"; 
private static final String SALT_VALUE = "16byte-salt-here"; 
private static final int ITERATIONS = 1; 

private static IvParameterSpec ivParameterSpec; 

public static String encryptHex(String value) throws Exception { 
    Key key = generateKey(); 

    Cipher c = Cipher.getInstance(_AES_CBC_PKCS5Padding); 
    ivParameterSpec = new IvParameterSpec(SALT_VALUE.getBytes()); 
    c.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec); 

    String valueToEncrypt = null; 
    String eValue = value; 
    for (int i = 0; i < ITERATIONS; i++) { 
//   valueToEncrypt = SALT_VALUE + eValue; // pre-pend salt - Length > sample length 
     valueToEncrypt = eValue;  // don't pre-pend salt Length = sample length 
     byte[] encValue = c.doFinal(valueToEncrypt.getBytes()); 
     eValue = Hex.encodeHexString(encValue); 
    } 
    return eValue; 
} 

public static String decryptHex(String value) throws Exception { 
    Key key = generateKey(); 

    Cipher c = Cipher.getInstance(_AES_CBC_PKCS5Padding); 
    ivParameterSpec = new IvParameterSpec(SALT_VALUE.getBytes()); 
    c.init(Cipher.DECRYPT_MODE, key, ivParameterSpec); 

    String dValue = null; 
    char[] valueToDecrypt = value.toCharArray(); 
    for (int i = 0; i < ITERATIONS; i++) { 
     byte[] decordedValue = Hex.decodeHex(valueToDecrypt); 
     byte[] decValue = c.doFinal(decordedValue); 
//   dValue = new String(decValue).substring(SALT_VALUE.length()); // when salt is pre-pended 
     dValue = new String(decValue); // when salt is not pre-pended 
     valueToDecrypt = dValue.toCharArray(); 
    } 
    return dValue; 
} 

private static Key generateKey() throws Exception { 
    // Key key = new SecretKeySpec(KEY_VALUE.getBytes(), _AES); // this was wrong 
    Key key = new SecretKeySpec(new BASE64Decoder().decodeBuffer(keyValueString), _AES); // had to un-Base64 the 'known' 24-byte key. 
    return key; 
} 

} 

Je ne peux pas créer une valeur chiffrée correspondant ni déchiffrer une valeur chiffrée donnée. Je suppose que c'est quelque chose à voir avec la façon dont je manipule le vecteur/sel initial. Je ne suis pas très crypto-savvy mais je pense que je devrais être capable de prendre l'exemple de texte clair et de produire la même valeur cryptée en Java que ColdFusion produite. Je suis capable de crypter/décrypter mes propres données avec mon code Java (donc je suis cohérent) mais je ne peux pas trouver ou déchiffrer l'exemple chiffré de ColdFusion.

J'ai accès à un service web local qui peut tester la sortie cryptée. L'échantillon de sortie ColdFusion donné passe/décrypte bien (bien sûr). Si j'essaie de déchiffrer le même échantillon avec mon code Java (en utilisant la clé et le sel), j'obtiens une erreur "Le bloc final n'est pas correctement rembourré". J'obtiens le même résultat net lorsque je passe ma tentative de cryptage (en utilisant la clé et le sel) au service web de test.

Des idées?

Répondre

4

est la valeur du Coldfusion ThisKey:

<cfset ThisKey = "a-24byte-key-string-here"> 

La même chaîne exacte qui est renvoyée par la fonction generateKey() java? Je crois qu'ils doivent être la même chaîne pour que le texte crypté généré soit le même.

Pour utiliser une clé fixe comme dans les FC, vous devrez peut-être suivre cela de la CF technote sur un cryptage fort:

Vous voudrez peut-être générer votre propre clé pour deux raisons:

  1. Vous souhaitez faire correspondre les détails d'autres logiciels de chiffrement.
  2. Vous voulez augmenter la résistance à la fissuration de vos données cryptées par techniques de cryptanalyse orientées motif.

Par exemple, pour créer un 32 octets clé à utiliser avec l'algorithme AES avec la valeur hexadécimale :

8738fed68e7677d374e0946c8f7bd3bb4f50f23717f9f3667b2419483959039c

que vous utilisez pour créer les fonctions ColdFusion BinaryDecode et ToBase64 la clé:

<cfset myKey = 
ToBase64(BinaryDecode("8738fed68e7677d374e0946c8f7bd3bb4f50f23717f9f3667b2419483959039c","Hex")> 
<cfset encrypted =Encrypt(myString, myKey, "AES")> 

EDIT: Il suffit de réaliser que la clé (comme vous l'avez mentionné dans votre commentaire) est base64, donc si la méthode « generateKey » en Java ressemble à:

private static Key generateKey() throws Exception { 
final byte[] decodedKey = new BASE64Decoder().decodeBuffer(KEY_VALUE); 
final Key key = new SecretKeySpec(decodedKey, _AES); 
return key; 
} 

Vous devriez être en or.

+0

Merci man - La méthode generateKey() crée un objet clé qui contient l'algorithme "AES" et un tableau d'octets de la clé connue afin qu'il corresponde. MAIS ... apparemment la clé de l'échantillon (passé dans un document doc était codé en bas64 et devait être désencodée avant que je puisse l'utiliser.) J'ai fait le changement et mis à jour le code Java de l'échantillon ... Tout va bien dans le monde ... pour l'instant... – JohnTheBarber