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

将Coldfusion加密代码转换为C#(再次),c#,encryption,coldfusion,base64,C#,Encryption,Coldfusion,Base64,我的任务再次是将用于单点登录的ColdFusion代码转换为C#,但时间紧迫。这一个和我回答的问题完全不同,所以我又回到了头脑中 最初的ColdFusion代码是在一个标记中执行的。我用缩写占位符替换了src和pwd变量,只是为了掩盖它们的实际值: //create a key to be used src="xxx"; pwd="abc"; // Base64 Decoding the key base64Decoder = createObject("java", "sun.misc.BA

我的任务再次是将用于单点登录的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);
//steps omitted here to create src string
string token = "xxx";
string key = "abc";
byte[] decodedKeyBytes = Convert.FromBase64String(key);
我还有一份来自另一方的文件,概述了创建单一登录的步骤,如下所示:

创建加密令牌

  • 创建纯文本(这对应于上面的变量src,以及我在C#中成功完成的部分)
  • 填充纯文本

  • 解码密钥(密钥对应于上面的变量pwd,并且必须是base 64解码;我想我已经成功地达到了这一点。)

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

  • 对密码文本进行编码(url编码)

我安装了BouncyCastle库,并试图利用这些库,但我仍停留在实际的加密步骤上。到目前为止,我的C#转换的开始看起来是这样的(令牌和键再次使用缩写占位符来掩盖实际值):

我知道这还不算太多,但我已经尝试了太多没用的东西,以至于我迷失了方向。最后,当我开始初始化密码时,我假设我需要这样的东西:

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); 
这个完全不同

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

不要让java代码把你甩了。忽略一些未使用的变量,它所做的工作与另一个线程上的
encrypt()
完全相同-除了使用“TripleDES”而不是“Blowfish”
encrypt()
隐藏了很多复杂性,但在内部它也做了同样的事情——使用相同的java类FWIW。这意味着你可以使用相同的C代码。正如您已经猜到的,您只需要更换加密引擎:

....
// initialize for EBC mode and PKCS5/PKCS7 padding
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new DesEdeEngine());
...
更新:

再详细说明一下,当您使用
加密(someUTF8String、base64密钥、算法、编码)
时,CF在内部执行与java代码相同的步骤:

  • 解码base64中的密钥,并为给定算法创建一个KeySpec对象,即

    //Base64解码密钥
    //CF可以使用不同的解码器,但整个过程是相同的
    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(算法);
    encodeCipher.init(1,secretKey);//1-加密模式
    raw=encodeCipher.doFinal(stringBytes)

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

    cipherText=ToBase64(原始)


  • 如您所见,java代码和
    加密
    做的事情完全相同

    啊,好的,谢谢你!至少我对密码初始化没有太在意。:)但我仍然有点不确定加密部分-在我的另一个问题的代码中,我只有静态密钥,但在这一部分中,我有一个密钥和一个动态生成的加密令牌,因此我不太确定如何在加密步骤中合并这两个密钥。编辑:在加密步骤中合并这两个密钥。也许我的大脑有些疲劳,但我并没有在你发布的内容中看到完整的画面。最初的CF/java代码只是一个基本的
    encrypt()
    。使用TripleDES类运行C#代码,您将得到相同的结果。他们的意思是“使用上面的代码生成一个用于“河豚”加密的“密钥”?运气好吗?看起来您只是在尝试转换cfscript代码。如果没有,你可以发布更多的细节,因为听起来好像有一块拼图丢失了。是的,我终于能够让这个工作刚刚-再次感谢你的帮助和非常清楚的解释,我真的很感谢!我没有意识到,正如您所指出的,encrypt()在幕后执行了这么多步骤;CF代码对我来说太不一样了,我在尝试重新创建每一个片段时都被挂断了。实际上,如果我不使用CF代码作为参考,那么我最好尝试将指令直接翻译成C我已经用成功的代码更新了我的帖子。是的,CF在很大程度上使用了java的核心加密库。由于只有一种方法可以使用该API,
    encrypt()
    在内部使用与任何其他java应用程序相同的方法。很高兴我能帮忙:)