我一直在到处寻找一些示例代码,介绍如何使用Bouncy Castle框架用标题中的加密加密一个简单的字符串。
此代码将在Windows Universal项目上运行。我以前尝试使用内置API进行加密,但在服务器上解密失败。
s = String.Format("{0}_{1}", s, DateTime.Now.ToString("ddMMyyyyHmmss"));
SymmetricKeyAlgorithmProvider algorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
IBuffer keymaterial = CryptographicBuffer.ConvertStringToBinary("[Key]", BinaryStringEncoding.Utf8);
CryptographicKey KEY = algorithm.CreateSymmetricKey(keymaterial);
IBuffer IV = CryptographicBuffer.ConvertStringToBinary("[IV]", BinaryStringEncoding.Utf8);
IBuffer data = CryptographicBuffer.ConvertStringToBinary(s, BinaryStringEncoding.Utf8);
IBuffer output = CryptographicEngine.Encrypt(KEY, data, IV);
return CryptographicBuffer.EncodeToBase64String(output);
服务器使用
public static string Encrypt(string text, byte[] key, byte[] iv, int keysize = 128, int blocksize = 128, CipherMode cipher = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
{
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.BlockSize = blocksize;
aes.KeySize = keysize;
aes.Mode = cipher;
aes.Padding = padding;
byte[] src = Encoding.UTF8.GetBytes(text);
using (ICryptoTransform encrypt = aes.CreateEncryptor(key, iv))
{
byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length);
encrypt.Dispose();
return Convert.ToBase64String(dest);
}
}
public static string Decrypt(string text, byte[] key, byte[] iv, int keysize = 128, int blocksize = 128, CipherMode cipher = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
{
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.BlockSize = blocksize;
aes.KeySize = keysize;
aes.Mode = cipher;
aes.Padding = padding;
byte[] src = Convert.FromBase64String(text);
using (ICryptoTransform decrypt = aes.CreateDecryptor(key, iv))
{
byte[] dest = decrypt.TransformFinalBlock(src, 0, src.Length);
decrypt.Dispose();
return Encoding.UTF8.GetString(dest); //Padding is invalid and cannot be removed.
}
}
但失败的原因是:
填充无效,无法删除。
初始化向量的长度必须与块大小相同
byte[] inputBytes = Encoding.UTF8.GetBytes(s);
byte[] IV = Encoding.UTF8.GetBytes("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
byte[] key = Encoding.UTF8.GetBytes("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
//Set up
AesEngine engine = new AesEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
Debug.WriteLine(IV.Length); //32
Debug.WriteLine(cipher.GetBlockSize()); //16
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV keyParamWithIv = new ParametersWithIV(keyParam, IV);
cipher.Init(true, keyParamWithIv); //Error Message thrown
byte[] outputBytes = new byte[cipher.GetOutputSize(inputBytes.Length)]; //cip
int length = cipher.ProcessBytes(inputBytes, outputBytes, 0);
cipher.DoFinal(outputBytes, length); //Do the final block
string encryptedInput = Convert.ToBase64String(outputBytes);
服务器上的长度为128。我怎么能强迫它是等长的?
下面是我使用的片段。它使用默认的内置System.Security.Cryptography。不需要是BC
/// <summary>
/// Encrypt a byte array using AES 128
/// </summary>
/// <param name="key">128 bit key</param>
/// <param name="secret">byte array that need to be encrypted</param>
/// <returns>Encrypted array</returns>
public static byte[] EncryptByteArray(byte[] key, byte[] secret)
{
using (MemoryStream ms = new MemoryStream())
{
using (AesManaged cryptor = new AesManaged())
{
cryptor.Mode = CipherMode.CBC;
cryptor.Padding = PaddingMode.PKCS7;
cryptor.KeySize = 128;
cryptor.BlockSize = 128;
//We use the random generated iv created by AesManaged
byte[] iv = cryptor.IV;
using (CryptoStream cs = new CryptoStream(ms, cryptor.CreateEncryptor(key, iv), CryptoStreamMode.Write))
{
cs.Write(secret, 0, secret.Length);
}
byte[] encryptedContent = ms.ToArray();
//Create new byte array that should contain both unencrypted iv and encrypted data
byte[] result = new byte[iv.Length + encryptedContent.Length];
//copy our 2 array into one
System.Buffer.BlockCopy(iv, 0, result, 0, iv.Length);
System.Buffer.BlockCopy(encryptedContent, 0, result, iv.Length, encryptedContent.Length);
return result;
}
}
}
/// <summary>
/// Decrypt a byte array using AES 128
/// </summary>
/// <param name="key">key in bytes</param>
/// <param name="secret">the encrypted bytes</param>
/// <returns>decrypted bytes</returns>
public static byte[] DecryptByteArray(byte[] key, byte[] secret)
{
byte[] iv = new byte[16]; //initial vector is 16 bytes
byte[] encryptedContent = new byte[secret.Length - 16]; //the rest should be encryptedcontent
//Copy data to byte array
System.Buffer.BlockCopy(secret, 0, iv, 0, iv.Length);
System.Buffer.BlockCopy(secret, iv.Length, encryptedContent, 0, encryptedContent.Length);
using (MemoryStream ms = new MemoryStream())
{
using (AesManaged cryptor = new AesManaged())
{
cryptor.Mode = CipherMode.CBC;
cryptor.Padding = PaddingMode.PKCS7;
cryptor.KeySize = 128;
cryptor.BlockSize = 128;
using (CryptoStream cs = new CryptoStream(ms, cryptor.CreateDecryptor(key, iv), CryptoStreamMode.Write))
{
cs.Write(encryptedContent, 0, encryptedContent.Length);
}
return ms.ToArray();
}
}
}
如果您确实需要BC,下面是一个基于https://github.com/bcgit/bc-csharp/blob/master/crypto/test/src/crypto/test/aesfasttest.cs的测试套件编写的快速测试,您可以根据需要进行调整
private static void TestBC()
{
//Demo params
string keyString = "jDxESdRrcYKmSZi7IOW4lw==";
string input = "abc";
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
byte[] iv = new byte[16]; //for the sake of demo
//Set up
AesEngine engine = new AesEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine); //CBC
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher); //Default scheme is PKCS5/PKCS7
KeyParameter keyParam = new KeyParameter(Convert.FromBase64String(keyString));
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv, 0, 16);
// Encrypt
cipher.Init(true, keyParamWithIV);
byte[] outputBytes = new byte[cipher.GetOutputSize(inputBytes.Length)];
int length = cipher.ProcessBytes(inputBytes, outputBytes, 0);
cipher.DoFinal(outputBytes, length); //Do the final block
string encryptedInput = Convert.ToBase64String(outputBytes);
Console.WriteLine("Encrypted string: {0}", encryptedInput);
//Decrypt
cipher.Init(false, keyParamWithIV);
byte[] comparisonBytes = new byte[cipher.GetOutputSize(outputBytes.Length)];
length = cipher.ProcessBytes(outputBytes, comparisonBytes, 0);
cipher.DoFinal(comparisonBytes, length); //Do the final block
Console.WriteLine("Decrypted string: {0}",Encoding.UTF8.GetString(comparisonBytes)); //Should be abc
}
加密方法 JavaScript
要求: 我有一个Ruby on rails应用程序,我需要执行以下操作。 以下字符串应使用3DES算法和工作密钥加密。ABJGTU9的加密值将是vV51P0OGXt0= 工作密钥为 A5157A0D77B24AEA868AD73288366826 以下文献中提到的3DES算法使用以下步骤进行数据加密: i.使用CBC密码模式和PKCS7填充的密钥的左侧部分加密数据。ii.使用CBC密码模式和无填充
我目前试图翻译一个简单的AES代码从C#到Python。我对这两种语言都很了解,但是我对加密领域(尤其是AES)一无所知。我以前用C#写过这个AES代码,但是现在我不知道如何在Python中工作(我使用PyCrypto,因为Python2.7没有内置的AES)。下面是我的C#代码: 请注意,对于Python,我还需要BlockSize=128、KeySize=256、Padding=PKCS7和C
问题内容: 我正在尝试使用128位AES加密(ECB)加密/解密字符串。我想知道的是如何向其中添加/删除PKCS7填充。看起来Mcrypt扩展可以处理加密/解密,但是必须手动添加/删除填充。 有任何想法吗? 问题答案: 让我们来看看。RFC 5652(加密消息语法)中描述了PKCS#7。 填充方案本身在第6.3节中给出。内容加密过程。它的本质是说:根据需要追加许多字节以填充给定的块大小(但至少一个
我只想用这3种模式测试openSSL中的AES:128192和256密钥长度,但我解密的文本与我的输入不同,我不知道为什么。此外,当我传递一个巨大的输入长度(比如1024字节)时,我的程序显示。。。我的意见总是一样的,但这并不重要,至少现在是这样。代码如下: 编辑: 当我将输出大小更改为而不是时,我得到了结果: 那么,是否有可能存在Outpus大小和IV大小的问题?它们应该有什么尺寸(AES-CB
我试图在CBC模式下使用AES和Crypto++库加密(和解密)一个文件 以下是我已经做的: 为了加密文件,我以二进制模式打开它,并将内容转储为字符串: 当我将尝试解密此文件时,我如何分别提取iv和密文?IV是16字节长,但在这里我完全迷失了,我不知道如何做。