将Coldfusion加密代码转换为C#(再次)

时间:2015-02-03 23:33:54

标签: c# encryption coldfusion base64

我再次负责将用于单点登录的ColdFusion代码转换为C#,并且我的运行时间很短。这个问题与我回答here的问题完全不同,所以我又回到了我的脑海里。

原始ColdFusion代码在< cfscript>中执行。标签。我用缩写的占位符替换了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#中成功完成的那部分)
  • 填写纯文本

  • 对密钥进行解码(密钥对应上面的变量pwd,并且必须基于64进行解码;我认为我已经成功地完成了这一点。)

  • 执行加密(使用上面获得的解码密钥和纯文本进行加密)

  • 对密文进行编码(网址编码)

我安装了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());

非常感谢任何建议/例子。

更新

感谢下面非常有用的答案,我能够使用以下代码实现这一点:

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

1 个答案:

答案 0 :(得分:0)

  

这个完全不同

没那么多;-)你已经回答了自己的问题。

不要让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代码相同的步骤:

  1. 从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);

  2. 接下来,它提取纯文本的UTF-8字节,即

    stringBytes = toString(src).getBytes("UTF8");

  3. CF然后创建一个密码,填充和加密纯文本,即:

    encodeCipher = createObject("java", "javax.crypto.Cipher").getInstance(algorithm); encodeCipher.init(1, secretKey); // 1 - ENCRYPT_MODE raw = encodeCipher.doFinal(stringBytes);

  4. 最后,CF将加密字节编码为base64,即:

    cipherText=ToBase64(raw);

  5. 正如您所看到的,java代码和encrypt完全相同。