2010-04-14 2 views
5

*** 달콤한 - ColdFusion의 키가 Base64로 인코딩되었음을 나타내는 CF Technote의 Edward Smith에게 감사드립니다. 수정을위한 generateKey() 참조Java 1.4.2에서 ColdFusion 암호화를 일치시키는 방법은 무엇입니까?

내 작업은 Java 1.4.2를 사용하여 암호화를 위해 주어진 ColdFusion 코드 샘플의 결과를 일치시키는 것입니다.

알려진/주어진 값 :

  • 24 바이트 키
  • 16 바이트 염 (IVorSalt)
  • 인코딩 육각
  • 이다
  • 암호화 알고리즘 AES/CBC/PKCS5Padding에
  • 샘플 일반 텍스트 값
  • ColdFusion 코드를 통과 한 후 샘플 일반 텍스트의 암호화 된 값

가정이 :는 ColdFusion 코드에 지정되지 않은 반복

  • 수 그래서 난 생각 하나 반복
  • 24 바이트 키 내가 생각 때문에 192 비트 암호화
을 감안할 때

/작업 ColdFusion에서 암호화 코드 샘플 :

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

내 자바 1.4.2 암호화/복호화 코드 스와 그 :

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

} 

일치하는 암호화 된 값을 만들거나 암호화 된 값을 해독 할 수 없습니다. 내 생각 엔 초기 벡터/염을 어떻게 처리하는지와 관련이있다.

저는 암호에 정통한 것은 아니지만 ColdFusion에서 생성 된 것처럼 샘플 텍스트를 가져 와서 Java에서 동일한 암호화 된 값을 생성 할 수 있어야한다고 생각합니다. Java 코드로 자신의 데이터를 암호화/해독 할 수 있으므로 일관성이 있습니다. 그러나 ColdFusion 샘플 암호화 값과 일치하거나 해독 할 수 없습니다.

나는 암호화 된 출력을 테스트 할 수있는 로컬 웹 서비스에 액세스 할 수 있습니다. 주어진 ColdFusion 출력 샘플은 물론 잘 전달/해독합니다. 실제 코드와 소금을 사용하여 Java 코드로 동일한 샘플을 해독하려고하면 "주어진 최종 블록에 적절히 패딩되지 않았습니다"라는 오류가 표시됩니다. 테스트 웹 서비스에 암호화 (실제 키와 소금 사용) 시도를 통과하면 같은 결과를 얻습니다.

어떤 아이디어? 자바 generateKey() 함수에서 반환

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

정확한 동일한 문자열 : ColdFusion의 ThisKey의 값이

답변

4

인가? 나는 그들이 생성 된 암호화 된 텍스트가 동일해야한다는 것과 동일한 문자열이어야 할 필요가 있다고 생각한다.

가 CF에서 그런 고정 키를 사용하려면 강력한 암호화에 CF technote에서이 작업을 수행해야 할 수 있습니다

:

당신은 두 가지 이유로 자신의 키를 생성 할 수 있습니다

  1. 다른 암호화 소프트웨어의 세부 정보를 일치시키고 싶습니다.
  2. 패턴 기반 암호 해독 기술을 사용하여 암호화 된 데이터의 크래킹에 대한 저항력을 높이고 싶습니다.

예를 들어, 16 진수 값으로 AES 알고리즘을 사용하는 키 32 바이트 만듭니다 :

8738fed68e7677d374e0946c8f7bd3bb4f50f23717f9f3667b2419483959039c을

작성하는 ColdFusion 함수 BinaryDecode 및 ToBase64을 사용 키 :

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

편집 : 당신은 황금해야

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

: 그냥 같은 자바에서 "generateKey"방법은 보이는, 그래서 만약 (당신은 당신의 코멘트에 언급 한 바와 같이) 키, base64로 인 것을 깨달았다.

+0

thanksKey - generateKey() 메서드는 알고리즘 "AES"와 알려진 키의 바이트 배열이 포함 된 Key 객체를 생성하여 일치시킵니다. 그러나 ... 분명히 샘플 키 (word doc로 전달 된 코드는 bas64로 인코딩되어 있으며 사용하기 전에 인코딩을 해제해야했습니다.)을 변경하고 샘플 Java 코드를 업데이트했습니다. 지금은 ... – JohnTheBarber

관련 문제