C#에서 (128 비트 AES)를 사용하여 임의의 IV로 CBC를 테스트하려고합니다.AES에서 패딩 CBC
내 질문에 해결하려면 12 바이트 입력 메시지가 있습니다. 조건은 PlainText가 블록 크기 (16 바이트)보다 작은 경우 사용할 패딩을 0x01로 시작한 다음 6 0x00으로 시작한다는 것입니다.
예 :
in ASCII PT = Pay Bob 100%
in hex PT = 50 61 79 20 42 6f 62 20 31 30 30 24
PT with Padding = 50 61 79 20 42 6f 62 20 31 30 30 24 01 00 00 00
나는을 것은 RijndaelManaged이 PaddingMode을 찾을 수있을 것 같지 않습니다.
다음 중 어떻게 할 수 있습니까?
- 가변 길이 패딩
편집 :
public class CBC
{
public CBC()
{
}
private static readonly byte[] SALT = new byte[]
{0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c};
public static byte[] EncryptCBC(string plainText, string passPhrase, PaddingMode paddingMode)
{
byte[] result;
using (RijndaelManaged cryptoProvider = new RijndaelManaged())
{
Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(passPhrase, SALT);
cryptoProvider.Mode = CipherMode.CBC;
cryptoProvider.GenerateIV(); // generate random IV
cryptoProvider.Padding = paddingMode;
cryptoProvider.Key = derivedKey.GetBytes(cryptoProvider.KeySize/8);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (ICryptoTransform encryptor = cryptoProvider.CreateEncryptor(cryptoProvider.Key, cryptoProvider.IV))
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
}
}
// concatenate iv to ciphertext
result = cryptoProvider.IV.Concat(msEncrypt.ToArray()).ToArray();
}
cryptoProvider.Clear();
}
return result;
}
public static string DecryptCBC(byte[] cipherTextBytes, string passPhrase, PaddingMode paddingMode)
{
string result = null;
using (RijndaelManaged cryptoProvider = new RijndaelManaged())
{
Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(passPhrase, SALT);
cryptoProvider.Mode = CipherMode.CBC;
// take the iv off the beginning of the ciphertext message
cryptoProvider.IV = cipherTextBytes.Take(cryptoProvider.BlockSize/8).ToArray();
cryptoProvider.Padding = paddingMode;//PaddingMode.ANSIX923;
cryptoProvider.Key = derivedKey.GetBytes(cryptoProvider.KeySize/8);
using (MemoryStream msEncrypt = new MemoryStream(cipherTextBytes.Skip(cryptoProvider.BlockSize/8).ToArray())) // skip the IV bytes
{
using (ICryptoTransform encryptor = cryptoProvider.CreateDecryptor(cryptoProvider.Key, cryptoProvider.IV))
{
using (CryptoStream cryptoStream = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Read))
{
byte[] plainTextBytes = new byte[cipherTextBytes.Length - cryptoProvider.BlockSize/8];
int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
result = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
cryptoStream.Close();
}
}
}
cryptoProvider.Clear();
}
return result;
}
}
내 패딩 기능
private byte[] PaddPlainTextBytes(byte[] plainTextBytes)
{
byte[] padding = utils.HexToBytes("01000000");
MemoryStream s = new MemoryStream();
s.Write(plainTextBytes, 0, plainTextBytes.Length);
s.Write(padding, 0, padding.Length);
byte[] paddedPt = s.ToArray();
return paddedPt;
}
방법 내 CBC
private void btnTestCBC_Click(object sender, EventArgs e)
{
string plainText = "Pay Bob 100%";
string passPhrase = "Thisismypassphrase";
ShowMessage(@"Plain Text = " + plainText);
byte[] pBytes = PaddPlainTextBytes(Encoding.ASCII.GetBytes(plainText));
string message = Encoding.ASCII.GetString(pBytes);
byte[] encryptedBytes = CBC.EncryptCBC(plainText: message, passPhrase: passPhrase, paddingMode: PaddingMode.None);
ShowMessage("Encrypted String = " + Encoding.ASCII.GetString(encryptedBytes));
ShowMessage("Encrypted HEX = " + utils.BytesToHex(encryptedBytes));
string decryptedString = CBC.DecryptCBC(encryptedBytes, passPhrase, PaddingMode.None);
ShowMessage("Deccrypted String = " + decryptedString);
}
CTR과 같이 패딩을 필요로하지 않는 작동 모드를 사용할 수도 있습니다. 아예 내장되어 있지 않습니다. – usr
패딩은 항상 고정 길이이며 정렬 기능이 아니라고 가정합니다. – leppie