메뉴

C#, PHP – RIJNDAEL 256bit 암/복호화

2015년 7월 23일 - C#.net, PHP

C#과 php간에 데이터를 주고 받아야 하는데
평문으로 통신하기에 무리가 있던 도중
기존에 사용하던 php 암호화 라이브러리와 연동되는 c# 코드를 발견~
살짝 수정해서 사용하는데 무리가 없음

기본은 128bit지만 256bit로 변경했음
php의 경우 블록에서 남는 부분을 zero로 채워넣기 때문에
c#에서 PaddingMode.Zeros를 설정해야 정상적으로 동작합니다.

Encryption.cs

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace TestClass
{
    class Encryption
    {
        private static byte[] rijnKey = Encoding.UTF8.GetBytes("abcdefg_abcdefg_abcdefg_abcdefg_");
        private static byte[] rijnIV = Encoding.UTF8.GetBytes("abcdefg_abcdefg_abcdefg_abcdefg_");

        public static String EncryptIt(String s)
        {
            String result;
            RijndaelManaged rijn = new RijndaelManaged();
            rijn.Mode = CipherMode.CBC;
            rijn.Padding = PaddingMode.Zeros; // php와의 연동에서 꼭 확인
            rijn.BlockSize = 256;

            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (ICryptoTransform encryptor = rijn.CreateEncryptor(rijnKey, rijnIV))
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(s);
                        }
                    }
                }
                result = Convert.ToBase64String(msEncrypt.ToArray());
            }
            rijn.Clear();

			result = Base64UrlEncode(result);

			return result;
        }

        public static String DecryptIt(String s)
        {
            String result;
            RijndaelManaged rijn = new RijndaelManaged();
            rijn.Mode = CipherMode.CBC;
            rijn.Padding = PaddingMode.Zeros;
            rijn.BlockSize = 256;

            s = Base64UrlDecode(s);

            using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(s)))
            {
                using (ICryptoTransform decryptor = rijn.CreateDecryptor(rijnKey, rijnIV))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader swDecrypt = new StreamReader(csDecrypt))
                        {
                            result = swDecrypt.ReadToEnd();
                        }
                    }
                }
            }
            rijn.Clear();

            return result;
        }

        public static string Base64UrlEncode(string arg)
        {
            arg = arg.Split('=')[0]; // Remove any trailing '='s
            arg = arg.Replace('+', '-'); // 62nd char of encoding
            arg = arg.Replace('/', '_'); // 63rd char of encoding
            return arg;
        }

        public static string Base64UrlDecode(string arg)
        {
            string s = arg;
            s = s.Replace('-', '+'); // 62nd char of encoding
            s = s.Replace('_', '/'); // 63rd char of encoding
            switch (s.Length % 4) // Pad with trailing '='s
            {
                case 0: break; // No pad chars in this case
                case 2: s += "=="; break; // Two pad chars
                case 3: s += "="; break; // One pad char
                default:
                    throw new System.Exception("Illegal base64url string!");
            }
            return s;
        }
    }
}

test.php

//Encryption function
function encryption($encrypt, $key, $iv)
{
    $td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_CBC, '');
    mcrypt_generic_init($td, $key, $iv);
    $encrypted = mcrypt_generic($td, $encrypt);
    $encode = base64_encode($encrypted);
    $encode = base64safeEncode($encode);
	mcrypt_generic_deinit($td);
    mcrypt_module_close($td);

    return $encode;
}

//Decryption function
function decryption($decrypt, $key, $iv)
{
    $decoded = base64safeDecode($decrypt);
    $decoded = base64_decode($decoded);
    $td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_CBC, '');
    mcrypt_generic_init($td, $key, $iv);
    $decrypted = mdecrypt_generic($td, $decoded);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);

    return trim($decrypted);
}

function base64safeEncode($data) {
	$data = str_replace("=", "", $data);
	$data = str_replace("+", "-", $data);
	$data = str_replace("/", "_", $data);
	return $data;
}

function base64safeDecode($data) {
    $data = str_replace("-", "+", $data);
    $data = str_replace("_", "/", $data);

    switch (strlen($data) % 4) {
        case 0: break;
        case 2: $data .= "=="; break;
        case 3: $data .= "="; break;
    }

    return $data;
}

$key = "abcdefg_abcdefg_abcdefg_abcdefg_";
$iv = "abcdefg_abcdefg_abcdefg_abcdefg_";

echo encryption("Hello world!", $key, $iv);
echo decryption("1ERpu8RaiyMqsXdjhCEu9IVMyQlz/A3fBR6vGbNxaVs=", $key, $iv);

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다