본문으로 건너뛰기

SEED 암호화

SEED는 KISA(한국인터넷진흥원)에서 개발한 128비트 블록 암호 알고리즘입니다. Easypay는 가맹점과 데이터를 주고받을 때, 민감한 정보(CI, 카드번호, 계좌번호 등)를 보호하기 위해 SEED128-CBC 방식을 사용합니다.

🔐 암호화 규격 (Specification)

연동 개발 시 반드시 아래 파라미터를 준수해야 복호화가 정상적으로 이루어집니다.

구분설정값비고
알고리즘SEED블록 암호화 (Block Cipher)
운영 모드CBCCipher Block Chaining
블록 크기128 bit16 Byte
패딩 (Padding)PKCS5Padding데이터가 16바이트 배수가 아닐 경우 채우는 방식
인코딩UTF-8문자열 처리 기준
출력 형식Base64암호화된 바이너리 데이터를 문자열로 변환
IV (초기화 벡터)"kicceasypay2018!"고정값 사용 (16 Byte 문자열)
Key (비밀 키)가맹점 Secret KeyEasypay 관리자 페이지에서 발급받은 키
주의사항
  • 시크릿 키(Secret Key)는 외부에 절대 노출되어서는 안 됩니다.
  • 고정된 IV 값 "kicceasypay2018!"를 사용합니다. 무작위 IV를 생성하거나 다른 값을 사용하면 서버에서 복호화 실패 오류가 발생합니다.

💻 언어별 구현 예제

아래 예제는 평문(Plain Text)을 암호화하여 Hex String으로 출력하는 코드입니다.

Java

Java에서는 KISA에서 제공하는 SEED128 클래스 또는 Bouncy Castle 라이브러리를 주로 사용합니다. 아래는 일반적인 javax.crypto 패키지를 사용한 예시입니다.

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class SeedUtil {
// 고정 IV
private static final String IV_STRING = "kicceasypay2018!";

public static String encrypt(String plainText, String secretKey) throws Exception {
// 키와 IV를 바이트 배열로 변환
byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
byte[] ivBytes = IV_STRING.getBytes(StandardCharsets.UTF_8);

// SEED 알고리즘 설정 (라이브러리에 따라 "SEED/CBC/PKCS5Padding" 지원 여부 확인 필요)
// * KISA 제공 라이브러리 사용 시 해당 API 문서 참조
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "SEED");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

Cipher cipher = Cipher.getInstance("SEED/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

byte[] encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));

// Hex String 변환 (StringBuilder 사용)
StringBuilder hexString = new StringBuilder();
for (byte b : encrypted) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
}

Node.js

Node.js의 crypto 모듈을 사용합니다. (OpenSSL 버전에 따라 SEED 지원 여부가 다를 수 있습니다.)

const crypto = require('crypto');

const IV = 'kicceasypay2018!'; // 고정 IV

function encryptSEED(plainText, secretKey) {
// 키는 16바이트(128bit)여야 함. 만약 길다면 자르거나 해시 처리 필요.
// 여기서는 그대로 사용한다고 가정.
const cipher = crypto.createCipheriv(
'seed-cbc',
Buffer.from(secretKey, 'utf8'),
Buffer.from(IV, 'utf8')
);

// PKCS5Padding은 createCipheriv가 자동 처리
let encrypted = cipher.update(plainText, 'utf8', 'hex');
encrypted += cipher.final('hex');

return encrypted;
}

Python

from Crypto.Cipher import SEED
from Crypto.Util.Padding import pad
import base64

IV = b'kicceasypay2018!' # 고정 IV (Bytes)

def encrypt_seed(plain_text, secret_key):
# 키와 데이터를 Bytes로 변환
key_bytes = secret_key.encode('utf-8')
data_bytes = plain_text.encode('utf-8')

# CBC 모드 객체 생성
cipher = SEED.new(key_bytes, SEED.MODE_CBC, IV)

# Padding(block size 16) 후 암호화
encrypted_bytes = cipher.encrypt(pad(data_bytes, SEED.block_size))

# HexString 변환
return encrypted_bytes.hex()

PHP

PHP는 openssl_encrypt 함수를 사용하여 간단하게 구현 가능합니다.

<?php
function encryptSEED($plainText, $secretKey) {
$iv = "kicceasypay2018!"; // 고정 IV

// seed-cbc 알고리즘 사용
// OPENSSL_RAW_DATA 옵션 사용 후 직접 base64_encode 권장
$encrypted = openssl_encrypt(
$plainText,
'seed-cbc',
$secretKey,
OPENSSL_RAW_DATA,
$iv
);

return bin2hex($encrypted);
}
?>