经过反复试验,我终于找到了在两端都可以使用的互补加密代码(在Oracle中加密,在.Net中解密)。代码如下。但是,它适用于最多15个字符的字符串。加密较大的字符串时,我得到的结果完全不同。有谁知道我如何修改以下内容才能不管字符串大小如何?
这是Oracle / PLSQL函数:
CREATE OR REPLACE FUNCTION Encrypt_Val(p_txt IN VARCHAR2, p_key IN VARCHAR2, p_iv IN VARCHAR2 := NULL)
RETURN RAW
IS
raw_txt RAW(4000);
raw_key RAW(4000);
raw_iv RAW(4000);
BEGIN
raw_txt := UTL_I18N.STRING_TO_RAW(data => p_txt, dst_charset => 'AL32UTF8');
raw_key := UTL_I18N.STRING_TO_RAW(data => p_key, dst_charset => 'AL32UTF8');
raw_iv := UTL_I18N.STRING_TO_RAW(p_iv, 'AL32UTF8');
RETURN DBMS_CRYPTO.encrypt(src => raw_txt,
key => raw_key,
typ => (DBMS_CRYPTO.ENCRYPT_AES256
+ DBMS_CRYPTO.chain_cbc
+ DBMS_CRYPTO.pad_pkcs5));
END ;
这是.Net代码:
public static class Encryption
{
public static string EncryptAES(string text, string key, string iv)
{
byte[] inputBytes = Encoding.UTF8.GetBytes(text);
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
using (var aesEncryption = AESCryptoProvider(keyBytes, ivBytes))
{
// Convert string to byte array
byte[] dest = new byte[inputBytes.Length];
// encryption
using (ICryptoTransform encrypt = aesEncryption.CreateEncryptor(aesEncryption.Key, aesEncryption.IV))
{
dest = encrypt.TransformFinalBlock(inputBytes, 0, inputBytes.Length);
encrypt.Dispose();
}
return BitConverter.ToString(dest).Replace("-", "");
}
}
public static string DecryptAES(string encryptedText, string key, string iv)
{
byte[] cypherText = StringToByteArray(encryptedText);
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
using (var aesDecryption = AESCryptoProvider(keyBytes, ivBytes))
{
// Convert string to byte array
byte[] dest = new byte[cypherText.Length];
// encryption
using (ICryptoTransform decrypt = aesDecryption.CreateDecryptor(aesDecryption.Key, aesDecryption.IV))
{
dest = decrypt.TransformFinalBlock(cypherText, 0, cypherText.Length);
decrypt.Dispose();
}
// Convert byte array to UTF8 string
return Encoding.UTF8.GetString(dest); ;
}
}
private static AesCryptoServiceProvider AESCryptoProvider(byte[] privateKeyByte, byte[] sharedIVKeyByte)
{
var aesProvider = new AesCryptoServiceProvider()
{
BlockSize = 128,
KeySize = 128,
IV = sharedIVKeyByte,
Key = privateKeyByte,
Mode = CipherMode.ECB,
Padding = PaddingMode.PKCS7
};
return aesProvider;
}
private static byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(hex.Substring(x, 2), 16)).ToArray();
}
}
从控制台调用.Net函数的代码:
private static void Main(string[] args)
{
string text = "Testing123";
string key = "12345678901234567890123456789012";
string iv = "26744a68b53dd87a";
string encryptedText = Encryption.EncryptAES(text, key, iv);
System.Console.WriteLine(".Net AES Encryption Result: '{0}'", encryptedText);
string decryptedText = Encryption.DecryptAES(encryptedText, key, iv);
System.Console.WriteLine(".Net AES Decryption Result: '{0}'", decryptedText);
}
在两端加密字符串 Testing123 (10个字符)时,我得到的结果是相同的:
但是,如果我尝试加密 Testing123456789 (16个字符):
有人知道如何解决此问题吗?