[英]How can i make an xcode encrypted string same as encrypted string in java
[英]How can I encrypt a string in Java to be the exact same as it is encrypted in ColdFusion?
我在ColdFusion中加密了數據,我需要能夠使用Java解密和加密到相同的精確值。 我希望有人可以幫助我。 我將指定ColdFusion中使用的所有內容,除了實際的PasswordKey,出於安全目的,我必須保密。 PasswordKey長度為23個字符。 它使用大寫和小寫字母,數字以及+和=符號。 我知道這有很多要問,但任何幫助都將不勝感激。
我嘗試使用我在網上找到的Java加密示例,只是用我們的CF應用程序中使用的23個字符替換下面的行:
private static final byte[] keyValue = new byte[] {'T', 'h', 'i', 's', 'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };`
但我得到錯誤:
java.security.InvalidKeyException: Invalid AES key length: 23 bytes
CF代碼是:
Application.PasswordKey = "***********************";
Application.Algorithm = "AES";
Application.Encoding = "hex";
<cffunction name="encryptValue" access="public" returntype="string">
<cfargument name="strEncryptThis" required="yes">
<cfreturn Encrypt(TRIM(strEncryptThis), Application.PasswordKey, Application.Algorithm, Application.Encoding)>
</cffunction>
<cffunction name="decryptValue" access="public" returntype="string">
<cfargument name="strDecryptThis" required="yes">
<cfreturn Decrypt(TRIM(strDecryptThis), Application.PasswordKey, Application.Algorithm, Application.Encoding)>
</cffunction>
您的密鑰很可能是Base64編碼密鑰(23個字符應解碼為大約16個字節,這是AES的128位密鑰的正確長度)。
因此,在您的java代碼中,首先通過Base64解碼器運行您的密鑰字符串,以獲得AES算法的適當長度(16字節)的byte []。
128但AES加密支持16字節的密鑰大小。
16 * 8 = 128位,即使在示例中密鑰是16字節。
聽起來你的密鑰是在Base64中所以使用Base64.decode(key或key.getBytes())來獲取字節數組,檢查它的16字節,否則通過填充使其成為16字節。
感謝大家的幫助。 我想發布我的最終解決方案供其他人使用。 我包括我的整個加密包代碼減去特定的密碼密鑰(再次出於安全考慮)。 此代碼創建與問題中列出的CF代碼相同的十六進制字符串,並將其解密回正確的英文文本字符串。
我在stackoverflow上發現了其他問題中的bytesToHex
和hexStringToByteArray
函數,所以我要感謝用戶們也分別是WeCouldStealAVan和Dave L. 我想我會研究其他基本的64位編碼器/解碼器,以防太陽的一個變得不可用,但這絕對適用於現在。 再次感謝。
package encryptionpackage;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.*;
public class encryption
{
// Note: The full CF default is "AES/ECB/PKCS5Padding"
private static final String ALGORITHM = "AES";
// The 24 character key from my CF app (base64 encoded)
// typically generated with: generateSecretKey("AES")
private static final String passKey = "***********************";
public static String encrypt(String valueToEnc) throws Exception
{
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encValue = c.doFinal(valueToEnc.getBytes());
String encryptedValue = bytesToHex(encValue);
return encryptedValue;
}
public static String decrypt(String encryptedValue) throws Exception
{
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = hexStringToByteArray(encryptedValue);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
private static Key generateKey() throws Exception
{
byte[] keyValue;
keyValue = new BASE64Decoder().decodeBuffer(passKey);
Key key = new SecretKeySpec(keyValue, ALGORITHM);
return key;
}
public static String bytesToHex(byte[] bytes)
{
final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] hexChars = new char[bytes.length * 2];
int v;
for ( int j = 0; j < bytes.length; j++ )
{
v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
public static byte[] hexStringToByteArray(String s)
{
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2)
{
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
}
AES加密僅支持128位,192位或256位的密鑰大小。
http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
您不能只接受任何字節數組並將其用作AES密鑰。 在上面看到的示例代碼中,示例巧妙地使用了16個字符,這對應於128位密鑰。
這是因為1個字符或者更確切地說1個字節對應於8個比特。
然后,16值字節數組將對應於16 * 8 = 128 bits
23個字符= 23 * 8 = 184 bits
,因此它是無效的密鑰大小。
您需要16個字符,24個字符或32個字符。
話雖這么說,僅使用字符進行AES加密是非常不安全的。 請使用適當且安全的隨機密鑰進行加密。
要生成安全且隨機的AES密鑰:
SecureRandom random = new SecureRandom();
byte [] secret = new byte[16];
random.nextBytes(secret);
http://docs.oracle.com/javase/6/docs/api/java/security/SecureRandom.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.