将 Coldfusion 加密代码转换为 C#(再次)
Converting Coldfusion encryption code to C# (again)
我再次接到任务,将用于单点登录的 ColdFusion 代码转换为 C#,运行 时间紧迫。这个与我回答的问题 完全不同,所以我又回到了我的头上。
原始 ColdFusion 代码在 标记中执行。我用缩写占位符替换了 src 和 pwd 变量,只是为了掩盖它们的实际值:
//create a key to be used
src="xxx";
pwd="abc";
// Base64 Decoding the key
base64Decoder = createObject("java", "sun.misc.BASE64Decoder");
desKeyData = base64Decoder.decodeBuffer(pwd);
// Initialize the constructor of DESedeKeySpec with private key
KeySpec=createObject("java", "javax.crypto.spec.DESedeKeySpec");
KeySpec=KeySpec.init(desKeyData);
// Generate the secret key using SecretKeyFactory
keyFac=createObject("java", "javax.crypto.SecretKeyFactory").getInstance("DESede");
secretKey =keyFac.generateSecret(KeySpec);
// Get CIPHER OBJ ready to use
decodecipher = createObject("java", "javax.crypto.Cipher").getInstance("DESede/ECB/PKCS5Padding");
decodecipher.init(2, secretKey);
encodecipher = createObject("java", "javax.crypto.Cipher").getInstance("DESede/ECB/PKCS5Padding");
encodecipher.init(1, secretKey);
stringBytes = toString(src).getBytes("UTF8");
raw = encodecipher.doFinal(stringBytes);
// Base64Encoding of generated cipher
cipherText=ToBase64(raw);
我还有一份对方的文档,概述了创建单点登录的步骤如下:
创建加密令牌
- 创建纯文本(这对应于上面的变量 src,那部分我已经在 C# 中成功完成)
填充纯文本
解码key(key对应上面的变量pwd,必须是base 64 decoded,我想我也成功到这里了)
进行加密(使用上面得到的解码密钥和明文进行加密)
对密文进行编码(url编码)
我安装了 BouncyCastle 库并尝试使用它们,但我卡在了实际的加密步骤上。到目前为止,我的 C# 转换的开头看起来像这样(令牌和密钥再次使用缩写占位符来掩盖实际值):
//steps omitted here to create src string
string token = "xxx";
string key = "abc";
byte[] decodedKeyBytes = Convert.FromBase64String(key);
我知道要继续做的事情并不多,但我已经尝试了很多没有用的东西,以至于我迷失了方向。最终,当我到达初始化密码的部分时,我假设我需要这样的东西:
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new DesEdeEngine());
非常感谢 suggestions/examples。
更新:
多亏了下面非常有用的回答,我才能够使用以下代码使它正常工作:
string token = "xxx";
string key = "abc";
byte[] base64DecodedKeyBytes = Convert.FromBase64String(key);
byte[] inputBytesToken = System.Text.Encoding.UTF8.GetBytes(token);
// initialize for EBC mode and PKCS5/PKCS7 padding
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new DesEdeEngine());
KeyParameter param = new KeyParameter(base64DecodedKeyBytes);
cipher.Init(true, param);
// encrypt and encode as base64
byte[] encryptedBytesToken = cipher.DoFinal(inputBytesToken);
string tokenBase64 = System.Convert.ToBase64String(encryptedBytesToken);
This one is completely different
没那么多 ;-) 您已经回答了自己的问题。
不要让 java 代码误导您。忽略一些未使用的变量,它与您的其他线程上的 encrypt()
做的事情完全相同 - 除了 "TripleDES" 而不是 "Blowfish"。 encrypt()
隐藏了很多复杂性,但在内部它做同样的事情——使用相同的 java 类 FWIW。这意味着您可以使用相同的 C# 代码。正如您已经猜到的那样,您只需要换出加密引擎:
....
// initialize for EBC mode and PKCS5/PKCS7 padding
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new DesEdeEngine());
...
更新:
只是详细说明一下,当您使用 encrypt( someUTF8String, base64Key, algorithm, encoding)
时,CF 在内部执行与您的 java 代码相同的步骤:
从base64解码密钥,并为给定算法创建一个KeySpec对象,即
// Base64 Decoding the key
// CF may use a different decoder, but the overall process is the same
base64Decoder = createObject("java", "sun.misc.BASE64Decoder");
....
secretKey =keyFac.generateSecret(KeySpec);
接下来提取明文的UTF-8字节,即
stringBytes = toString(src).getBytes("UTF8");
CF然后创建一个密码,填充并加密纯文本,即:
encodeCipher = createObject("java", "javax.crypto.Cipher").getInstance(algorithm);
encodeCipher.init(1, secretKey); // 1 - ENCRYPT_MODE
raw = encodeCipher.doFinal(stringBytes);
最后CF将加密后的字节编码为base64,即:
cipherText=ToBase64(raw);
正如您所看到的,java 代码和 encrypt
执行完全相同的操作。
我再次接到任务,将用于单点登录的 ColdFusion 代码转换为 C#,运行 时间紧迫。这个与我回答的问题
原始 ColdFusion 代码在
//create a key to be used
src="xxx";
pwd="abc";
// Base64 Decoding the key
base64Decoder = createObject("java", "sun.misc.BASE64Decoder");
desKeyData = base64Decoder.decodeBuffer(pwd);
// Initialize the constructor of DESedeKeySpec with private key
KeySpec=createObject("java", "javax.crypto.spec.DESedeKeySpec");
KeySpec=KeySpec.init(desKeyData);
// Generate the secret key using SecretKeyFactory
keyFac=createObject("java", "javax.crypto.SecretKeyFactory").getInstance("DESede");
secretKey =keyFac.generateSecret(KeySpec);
// Get CIPHER OBJ ready to use
decodecipher = createObject("java", "javax.crypto.Cipher").getInstance("DESede/ECB/PKCS5Padding");
decodecipher.init(2, secretKey);
encodecipher = createObject("java", "javax.crypto.Cipher").getInstance("DESede/ECB/PKCS5Padding");
encodecipher.init(1, secretKey);
stringBytes = toString(src).getBytes("UTF8");
raw = encodecipher.doFinal(stringBytes);
// Base64Encoding of generated cipher
cipherText=ToBase64(raw);
我还有一份对方的文档,概述了创建单点登录的步骤如下:
创建加密令牌
- 创建纯文本(这对应于上面的变量 src,那部分我已经在 C# 中成功完成)
填充纯文本
解码key(key对应上面的变量pwd,必须是base 64 decoded,我想我也成功到这里了)
进行加密(使用上面得到的解码密钥和明文进行加密)
对密文进行编码(url编码)
我安装了 BouncyCastle 库并尝试使用它们,但我卡在了实际的加密步骤上。到目前为止,我的 C# 转换的开头看起来像这样(令牌和密钥再次使用缩写占位符来掩盖实际值):
//steps omitted here to create src string
string token = "xxx";
string key = "abc";
byte[] decodedKeyBytes = Convert.FromBase64String(key);
我知道要继续做的事情并不多,但我已经尝试了很多没有用的东西,以至于我迷失了方向。最终,当我到达初始化密码的部分时,我假设我需要这样的东西:
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new DesEdeEngine());
非常感谢 suggestions/examples。
更新:
多亏了下面非常有用的回答,我才能够使用以下代码使它正常工作:
string token = "xxx";
string key = "abc";
byte[] base64DecodedKeyBytes = Convert.FromBase64String(key);
byte[] inputBytesToken = System.Text.Encoding.UTF8.GetBytes(token);
// initialize for EBC mode and PKCS5/PKCS7 padding
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new DesEdeEngine());
KeyParameter param = new KeyParameter(base64DecodedKeyBytes);
cipher.Init(true, param);
// encrypt and encode as base64
byte[] encryptedBytesToken = cipher.DoFinal(inputBytesToken);
string tokenBase64 = System.Convert.ToBase64String(encryptedBytesToken);
This one is completely different
没那么多 ;-) 您已经回答了自己的问题。
不要让 java 代码误导您。忽略一些未使用的变量,它与您的其他线程上的 encrypt()
做的事情完全相同 - 除了 "TripleDES" 而不是 "Blowfish"。 encrypt()
隐藏了很多复杂性,但在内部它做同样的事情——使用相同的 java 类 FWIW。这意味着您可以使用相同的 C# 代码。正如您已经猜到的那样,您只需要换出加密引擎:
....
// initialize for EBC mode and PKCS5/PKCS7 padding
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new DesEdeEngine());
...
更新:
只是详细说明一下,当您使用 encrypt( someUTF8String, base64Key, algorithm, encoding)
时,CF 在内部执行与您的 java 代码相同的步骤:
从base64解码密钥,并为给定算法创建一个KeySpec对象,即
// Base64 Decoding the key // CF may use a different decoder, but the overall process is the same base64Decoder = createObject("java", "sun.misc.BASE64Decoder"); .... secretKey =keyFac.generateSecret(KeySpec);
接下来提取明文的UTF-8字节,即
stringBytes = toString(src).getBytes("UTF8");
CF然后创建一个密码,填充并加密纯文本,即:
encodeCipher = createObject("java", "javax.crypto.Cipher").getInstance(algorithm); encodeCipher.init(1, secretKey); // 1 - ENCRYPT_MODE raw = encodeCipher.doFinal(stringBytes);
最后CF将加密后的字节编码为base64,即:
cipherText=ToBase64(raw);
正如您所看到的,java 代码和 encrypt
执行完全相同的操作。