C#, Java 간 암복호화를 사용할 일이 있어서 정리해봅니다.
처리 방법은 2가지가 있습니다.
1. TransformFinalBlock : 바이트 전체를 한번에 처리
2. CryptoStream : 스트림 단위로 잘라서 처리 1MB 이상이면 권장된다고 합니다!
using System;
using System.Security.Cryptography;
using System.Text;
namespace ConsoleApp1
{
class Program
{
private static readonly string KEY = "0123456789abcdef0123456789abcdef"; // 32-byte
private static readonly string IV = "abcdef9876543210"; // 16-byte
private static Aes aes;
static void Main(string[] args)
{
aes = Aes.Create();
aes.Key = Encoding.UTF8.GetBytes(KEY); //CBC므로 32바이트
aes.IV = Encoding.UTF8.GetBytes(IV); //16바이트 (첫 XOR 값)
aes.Mode = CipherMode.CBC; //16바이트 단위로 XOR 처리
aes.Padding = PaddingMode.PKCS7; //패딩 끝 부분 바이트 처리 (부족한 길이 반복)
string originalText = "Hello, AES-256!";
Console.WriteLine("Original: " + originalText);
string encryptedText = Encrypt(originalText);
Console.WriteLine("Encrypted: " + encryptedText);
string decryptedText = Decrypt(encryptedText);
Console.WriteLine("Decrypted: " + decryptedText);
}
static string Encrypt(string plainText)
{
ICryptoTransform encryptor = aes.CreateEncryptor();
byte[] inputBytes = Encoding.UTF8.GetBytes(plainText);
//****************************************************************
//통 Block 방식
byte[] encryptedBytes = encryptor.TransformFinalBlock(inputBytes, 0, inputBytes.Length);
return Convert.ToBase64String(encryptedBytes); //통신용이라면 base64가 안전 (아니면 그냥 UTF8로 해도 괜찮습니다!)
//****************************************************************
//Stream 방식 (1MB 이상이면 스트림 방식 권장)
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(inputBytes, 0, inputBytes.Length);
cs.FlushFinalBlock();
}
return Convert.ToBase64String(ms.ToArray());
}
}
static string Decrypt(string encryptedText)
{
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
byte[] encryptedBytes = Convert.FromBase64String(encryptedText); //Encrypt 후반에 base64를 썻는지에 따라 처리!
//****************************************************************
//통 Block 방식
byte[] decryptedBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
return Encoding.UTF8.GetString(decryptedBytes);
//****************************************************************
//Stream 방식 (1MB 이상이면 스트림 방식 권장)
using (MemoryStream ms = new MemoryStream(encryptedBytes))
{
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (MemoryStream result = new MemoryStream())
{
cs.CopyTo(result);
return Encoding.UTF8.GetString(result.ToArray());
}
}
}
}
}
}
C#가 호환되는 자바쪽 소스 (GPT가 알려준 소스..!)
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class Test {
// 주어진 AES 256-bit (32-byte) Key와 16-byte IV
private static final String KEY = "0123456789abcdef0123456789abcdef"; // 32-byte
private static final String IV = "abcdef9876543210"; // 16-byte
public static String encrypt(String plainText) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(), "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encrypted);
}
public static String decrypt(String encryptedText) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(), "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes());
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
byte[] decodedBytes = Base64.getDecoder().decode(encryptedText);
byte[] decrypted = cipher.doFinal(decodedBytes);
return new String(decrypted, "UTF-8");
}
public static void main(String[] args) {
try {
String originalText = "Hello, AES-256!";
System.out.println("Original: " + originalText);
String encryptedText = encrypt(originalText);
System.out.println("Encrypted: " + encryptedText);
String decryptedText = decrypt(encryptedText);
System.out.println("Decrypted: " + decryptedText);
} catch (Exception e) {
e.printStackTrace();
}
}
}
'C# > Console' 카테고리의 다른 글
[C#] 프로세스 실행 및 대기 (Process.Start , Process.WaitForExit) (0) | 2024.01.30 |
---|---|
[C#] 금액 (숫자) -> 한글 (원)로 변환하기 (0) | 2023.01.23 |
[C#] StructLayout : 클래스/구조체 크기 설정 (0) | 2022.08.03 |
[C#] 제이슨 JSON (JObject, JArray, Serialize, Deserialize) (0) | 2022.06.30 |
[C#] 내 아이피 주소 보기 IPv4, IPv6 (0) | 2022.03.07 |