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

标签 c# encryption coldfusion base64

我再次接到任务,将用于单点登录的 ColdFusion 代码转换为 C#,但时间紧迫。这与我回答的问题完全不同 here ,所以我又回到了我的头上。

原始的 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);

我还有一份来自对方的文档,概述了创建单点登录的步骤如下:

创建加密 token

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

  • 解码key(key对应上面的变量pwd,必须是base 64 decoded,我想我也成功走到这一步了。)

  • 进行加密(使用上面得到的解码 key 和明文进行加密)

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

我安装了 BouncyCaSTLe 库并尝试使用它们,但我卡在了实际的加密步骤上。到目前为止,我的 C# 转换的开始看起来像这样( token 和 key 再次使用缩写占位符来掩盖实际值):

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

最佳答案

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

  1. 从 base64 解码 key ,并为给定算法创建一个 KeySpec 对象,即

    //Base64解码 key //CF可能使用了不同的decoder,但是整体流程是一样的 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(算法); encodeCipher.init(1, secretKey);//1 - 加密模式 raw = encodeCipher.doFinal(stringBytes);

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

    cipherText=ToBase64(raw);

如您所见,java 代码和encrypt 做的事情完全一样。

关于c# - 将 Coldfusion 加密代码转换为 C#(再次),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28310827/

相关文章:

c# - 解密过程中 Winforms 数据 GridView 滞后

coldfusion - 在Coldfusion中创建Word文档-如何进行页码编号?

time - 了解浏览器时间轴

javascript - 当浏览器关闭时将 Flex 数据发送到 SQL(在 window.onbeforeunload 上)

c# - 如果有条件地执行任务,异步方法应该做什么?

c# - 无法安装 Entity Framework Power Tools

c# - SQL Server CE 抛出不兼容异常

c# - 管理列表项的困难

python - 如何在不再次生成 key 对的情况下进行加密/解密?

java - 服务器如何将数字证书传递给客户端/浏览器