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