Skip to content

SM4 암호화와 복호화 온라인 도구

SM4 복호화가 실패하면 모드·패딩·IV·인코딩 중 틀린 항목을 찾아 수정안을 제시합니다. 브라우저에서만 실행, 업로드 없음. ECB·CBC·CTR·CFB·OFB, PKCS#7·제로·패딩 없음.

트래킹 없음 브라우저 실행 무료
암호화는 전부 브라우저에서 실행되며, 입력한 키와 데이터는 이 기기를 벗어나지 않습니다.
암호문
같은 결과를 내는 OpenSSL 명령

OpenSSL 3이 필요합니다. 명령에는 입력한 키가 포함됩니다.

GB/T 32907-2016 SM4 테스트 벡터

이 페이지가 실행하는 엔진으로 빌드 시점에 계산한 값입니다. 직접 구현한 SM4를 이 값과 대조해 검증하세요.
0123456789abcdeffedcba9876543210
평문 0123456789abcdeffedcba9876543210
1회 암호화한 암호문 681edf34d206965e86b3e94f536e4246
1,000,000회 암호화한 암호문 595298c7c6fd271f0402f804c33d3f66
SM4 엔진은 GB/T 32907-2016 부록 A의 두 벡터로 테스트했으며, ECB, CBC, CTR, CFB, OFB 모드에서 OpenSSL 3과 교차 검증했습니다. 라이브러리 기본값은 OpenSSL, Node.js, sm-crypto, gm-crypt, gmssl, 그리고 Go 라이브러리 두 개를 직접 실행하고 Hutool과 BouncyCastle의 소스를 읽어 확인했습니다. — Go Tools 보안 팀 · Sep 11, 2026

암호 도구를 만드는 개발자가 작성하고 검토했습니다. 이 페이지에 인용한 모든 암호문과 바이트 수는 도구의 엔진으로 계산했으며 테스트로 확인했습니다.

SM4 핵심 요약

SM4 키 길이

16바이트 정확히 128비트, 즉 16바이트이며 hex 32자리 또는 ASCII 문자 16개로 씁니다. 192비트나 256비트 SM4 키는 없습니다.

GB/T 32907 테스트 벡터

681edf34d206965e86b3e94f536e4246 키와 평문이 0123456789abcdeffedcba9876543210일 때, 1회 암호화하면 681edf34d206965e86b3e94f536e4246이 나옵니다.

SM4 블록 크기와 라운드 수

32라운드 16바이트(128비트) 블록을 32라운드에 걸쳐 암호화합니다.

CBC에서 IV가 틀리면 항상 오류가 나나요?

처음 16바이트 아닙니다. 처음 16바이트만 잘못 복호화되고, 마지막 블록의 패딩은 그대로 검증을 통과합니다.

SM4란 무엇인가요?

SM4는 중국 상용 암호 표준에 속한 블록 암호입니다. GM/T 0002-2012로 처음 발표된 뒤 국가 표준 GB/T 32907-2016(2017년 3월 1일 시행)이 되었고, 2021년 개정을 통해 국제 표준 ISO/IEC 18033-3에 추가되었습니다. 같은 128비트 키로 암호화와 복호화를 모두 수행하는 대칭 암호이며, 128비트 블록, 즉 16바이트씩 처리합니다. AES와 같은 블록 크기입니다.

내부적으로는 각 블록을 32비트 워드 4개로 나누어 32라운드를 거칩니다. 매 라운드에서 워드 3개를 라운드 키와 섞고, 그 결과를 8비트 S-box와 선형 변환에 통과시킨 뒤 네 번째 워드에 합칩니다. 32개의 라운드 키는 두 종류의 고정 상수를 사용해 키로부터 유도되며, 복호화는 라운드 키를 역순으로 적용하는 같은 연산입니다.

블록 암호 자체는 정확히 16바이트만 처리할 수 있으므로, 실제 데이터는 항상 운영 모드를 거칩니다. 이 도구는 고전적인 다섯 가지 모드를 지원합니다. ECB와 CBC는 블록 단위로 동작해 패딩이 필요하고, CTR, CFB, OFB는 SM4를 스트림 암호처럼 동작하게 해 패딩이 전혀 필요 없습니다. 복호화 실패는 대부분 SM4 자체와는 무관합니다. 양쪽이 모드, 패딩, IV, 텍스트 인코딩, 키 문자열을 바이트로 바꾸는 방식을 서로 다르게 가정한 것이 원인이며, 그냥 "SM4"라고만 썼을 때의 의미조차 라이브러리마다 다릅니다.

브라우저에 내장된 Web Crypto API는 SM4를 지원하지 않으므로, 이 페이지는 자체 구현을 싣고 로컬에서 실행합니다. 이 구현은 GB/T 32907의 테스트 벡터 두 개로 테스트되었고, 모든 모드에서 OpenSSL 3과 교차 검증되었습니다.

// SM4-CBC with PKCS#7 padding using Node.js and its bundled OpenSSL 3.
// Key and IV are both exactly 16 bytes (32 hex digits).
const crypto = require('node:crypto');

const key = Buffer.from('0123456789abcdeffedcba9876543210', 'hex');
const iv = Buffer.from('fedcba98765432100123456789abcdef', 'hex');

const cipher = crypto.createCipheriv('sm4-cbc', key, iv);
const ciphertext = Buffer.concat([cipher.update('hello', 'utf8'), cipher.final()]);
console.log(ciphertext.toString('base64')); // fUQPRg2HAXHGz5ZslzCpSQ==

const decipher = crypto.createDecipheriv('sm4-cbc', key, iv);
const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
console.log(plaintext.toString('utf8')); // hello

SM4 도구의 주요 기능

복호화 실패 원인을 알려 줍니다

복호화가 실패하면 암호문 인코딩, 키 형식, 모드, IV, 패딩, 텍스트 인코딩을 바꿔 가며 다시 시도하고, 읽을 수 있는 텍스트가 나오는 설정을 보여 줍니다.

문제를 자주 일으키는 라이브러리 프리셋

클릭 한 번으로 OpenSSL, Hutool, sm-crypto, gm-crypt, tjfoc/gmsm의 기본값을 적용합니다. 이 라이브러리들은 그냥 "SM4"가 ECB인지 CBC인지조차 서로 다르게 해석합니다.

5가지 모드, 3가지 패딩, UTF-8 또는 GBK

ECB, CBC, CTR, CFB, OFB 모드와 PKCS#7, 제로 패딩, 패딩 없음을 지원합니다. 평문은 UTF-8 또는 GBK를 쓸 수 있으며, GBK는 오래된 Java 코드가 중국어 Windows에서 만들어 내는 인코딩입니다. GCM은 지원하지 않습니다.

SM4 키와 IV: 무작위 생성 또는 hex·텍스트·Base64 입력

클릭 한 번으로 16바이트 무작위 키나 IV를 생성하거나, 코드에 적힌 형식 그대로 입력하세요. 실시간 바이트 카운터로 정확히 16바이트인지 먼저 확인한 다음 다른 원인을 찾을 수 있습니다.

페이지에 실린 GB/T 32907 테스트 벡터

부록 A의 두 결과를 표로 보여 주고 클릭 한 번으로 불러올 수 있어, 어떤 SM4 구현이든 표준과 대조해 검증할 수 있습니다.

같은 결과를 내는 OpenSSL 명령

모든 결과에 그 결과를 재현하는 openssl enc 명령이 함께 표시되므로, 터미널에서 직접 확인하거나 동료에게 전달할 수 있습니다.

모든 처리를 브라우저에서 실행

SM4 엔진은 로컬에서 실행됩니다. 키와 데이터는 페이지를 벗어나지 않으며, 오프라인에서도 계속 동작합니다.

주요 라이브러리의 SM4 기본값

OpenSSL 3 (openssl enc)

-sm4 = CBC

-sm4-sm4-cbc의 별칭입니다. -K-iv는 hex를 받고, -nopad를 주지 않는 한 PKCS#7이 켜져 있으며, -base64 -A를 붙이지 않으면 원시 바이트를 출력합니다. 길이가 틀린 -K는 경고만 표시된 채 잘리거나 0으로 채워집니다.

Java: Hutool SmUtil.sm4(key)

ECB · PKCS#7

Hutool은 SM4라는 이름만 넘기고, BouncyCastle은 이를 ECB와 PKCS#7(JCE 이름은 PKCS5Padding)로 실행합니다. 문자열 메서드는 UTF-8을 쓰고 encryptHex는 소문자 hex를 출력합니다. CBC를 쓰려면 new SM4(Mode.CBC, Padding.PKCS5Padding, key, iv)를 사용하세요.

Java: BouncyCastle Cipher.getInstance("SM4")

ECB · PKCS#7

IV가 필요한 모드에서 IV를 받지 못하면, 암호화는 조용히 무작위 IV를 생성하고 복호화는 no IV set when one expected를 던집니다. 따라서 그 IV를 저장하지 않고 암호화한 암호문은 어디에서도 복호화할 수 없습니다.

JavaScript: sm-crypto

ECB · hex 키

sm4.encrypt(data, key)는 기본값이 ECB와 PKCS#7이고, 키를 32자리 hex 문자열로 받으며 소문자 hex를 반환합니다. mode: 'cbc'일 때만 모드가 바뀌고, 그 밖의 값은 조용히 ECB로 남습니다. sm-crypto-v2도 동작은 같지만, CBC에 iv를 주지 않으면 전부 0인 IV를 사용합니다.

JavaScript: gm-crypt

CBC · 텍스트 키 · Base64

기본값은 CBC이며, 키와 IV를 16자 UTF-8 문자열로 받고 Base64를 반환합니다. 바이트가 유효한 UTF-8이 아닌 키는 아예 넘길 수 없습니다.

Python: gmssl CryptSM4

PKCS#7 · 키를 16바이트로 자름

crypt_ecbcrypt_cbc 중 무엇을 호출하느냐로 모드가 정해집니다. set_key는 처음 16바이트만 읽으므로 더 긴 키는 조용히 잘리고, 키가 틀리면 대개 오류 대신 빈 바이트열을 반환합니다.

Go: tjfoc/gmsm sm4

기본 IV는 전부 0

Sm4CbcSetIV를 호출하기 전까지 전부 0으로 남는 패키지 수준 IV를 사용하고, CFB와 OFB에서도 PKCS#7로 패딩하며, 언패딩 오류를 버립니다. 그래서 키가 틀려도 오류 없이 nil을 반환합니다.

SM4 암호화와 복호화 예시

GB/T 32907 테스트 벡터 (ECB, 패딩 없음)

키 0123456789abcdeffedcba9876543210, 평문(hex) 0123456789abcdeffedcba9876543210
681edf34d206965e86b3e94f536e4246

GB/T 32907-2016 부록 A의 예제 1입니다. 키와 평문이 같은 128비트 값이며, 한 번 암호화하면 681edf34d206965e86b3e94f536e4246이 됩니다. 그 출력을 다시 암호화하는 과정을 총 100만 번 반복하면 595298c7c6fd271f0402f804c33d3f66이 나옵니다. 두 값 모두 이 페이지의 테스트 벡터 표에 실려 있으며, 지금 사용 중인 것과 같은 엔진으로 계산한 값입니다. GB/T 32907 테스트 벡터 버튼을 누르면 첫 번째 벡터가 로드됩니다.

CBC + PKCS#7: 텍스트 입력, Base64 출력

키 0123456789abcdeffedcba9876543210, IV fedcba98765432100123456789abcdef, 평문: SM4 interop test: order 20260911-0042
Wi6BuLpov8RndEfedUyLXFvDRnLMoo7T6O04Q83IzKDuDvPQ2S5clq+cEQXMvy/y

평문은 UTF-8로 37바이트입니다. PKCS#7 패딩을 붙이면 16바이트 블록 3개인 48바이트가 되고, 이를 Base64로 쓰면 64자가 됩니다. 예시 불러오기 버튼을 누르면 정확히 이 값들이 채워지며, OpenSSL 패널에는 터미널에서 같은 Base64 문자열을 재현하는 명령이 표시됩니다.

CBC에서 IV가 틀리면: 처음 16바이트만 깨짐

위의 암호문을 복호화하면서 IV로 00000000000000000000000000000000 사용
알아볼 수 없는 16바이트 + ": order 20260911-0042"

CBC는 IV를 첫 블록에만 섞고 PKCS#7 패딩은 마지막 블록에 있으므로, 패딩 검사는 그대로 통과하고 OpenSSL도 오류를 내지 않습니다. 이 페이지는 첫 블록을 읽을 수 없다는 점을 감지해, 키와 모드는 맞고 IV가 문제라는 것, 혹은 암호문의 처음 16바이트 자체가 IV라는 것을 알려 줍니다.

SM4 암호화와 복호화 도구 사용 방법

  1. 1

    라이브러리 프리셋 또는 모드와 패딩 선택

    상대 쪽 라이브러리를 안다면 라이브러리 기본값 맞추기에서 고르세요. 모른다면 암호화하기 또는 복호화하기를 선택하고 모드와 패딩을 맞춥니다. 스트림 모드(CTR, CFB, OFB)에는 패딩이 없으므로 패딩 선택기가 비활성화됩니다.

  2. 2

    키와 IV 입력

    둘 다 정확히 16바이트입니다. 문자열이 쓰인 형식(hex, 텍스트, Base64)을 고르고 바이트 카운터가 초록색으로 바뀌는지 확인하세요. 무작위 생성 버튼을 누르면 새 값이 생성됩니다.

  3. 3

    입력값 붙여넣기

    암호화할 때는 텍스트(UTF-8 또는 GBK)를 입력하거나 hex 바이트를 붙여넣습니다. 복호화할 때는 암호문을 붙여넣고 Base64인지 hex인지 지정합니다. 결과는 입력하는 즉시 갱신됩니다.

  4. 4

    결과 복사 또는 왕복 검증

    출력을 복사하거나, '이 암호문 복호화' 버튼을 눌러 같은 키와 IV를 유지한 채 복호화 탭으로 넘깁니다. OpenSSL 패널에는 같은 결과를 재현하는 명령이 표시됩니다.

  5. 5

    복호화가 실패하면 진단 결과 확인

    진단 결과에는 입력값이 읽을 수 있는 텍스트로 복호화되는 설정이 나열됩니다. 클릭 한 번으로 적용하거나, 처음 16바이트만 실패했다면 안내 문구를 읽어 보세요. 이 경우 원인은 IV입니다.

SM4 복호화가 실패하는 이유

hex 키를 텍스트로 읽음

32자짜리 hex 문자열은 hex로 디코딩할 때만 16바이트입니다. 텍스트로 읽으면 32바이트가 되어 SM4에서 거부되고, 키를 조용히 자르거나 채우는 코드에서는 아예 다른 키가 됩니다.

✗ 오류
키 (텍스트): 0123456789abcdeffedcba9876543210  -> 32바이트, 거부됨
✓ 정상
키 (hex):    0123456789abcdeffedcba9876543210  -> 16바이트

CBC 암호문을 ECB로 복호화

양쪽은 같은 모드를 써야 합니다. CBC 암호문을 ECB로 복호화하면 모든 블록이 깨지고, 대개 마지막의 패딩 검사에서도 실패합니다.

✗ 오류
encrypt: SM4/CBC/PKCS5Padding
decrypt: SM4/ECB/PKCS5Padding  -> bad decrypt
✓ 정상
encrypt: SM4/CBC/PKCS5Padding
decrypt: SM4/CBC/PKCS5Padding, 같은 IV

다른 IV 사용

CBC에서는 IV가 틀려도 오류가 나지 않습니다. 처음 16바이트만 깨지고 나머지는 정상적으로 복호화됩니다. 평문 앞부분만 깨졌다면 양쪽의 IV를 비교하세요.

✗ 오류
복호화 IV 00000000000000000000000000000000
-> 알아볼 수 없는 16바이트 + ": order 20260911-0042"
✓ 정상
복호화 IV fedcba98765432100123456789abcdef
-> "SM4 interop test: order 20260911-0042"

Base64 암호문을 hex로 처리

Base64와 hex는 같은 바이트를 적는 두 가지 방식입니다. 한쪽을 다른 쪽으로 읽으면 블록 암호에 처음부터 잘못된 입력이 들어갑니다.

✗ 오류
Wi6BuLpov8RndEfedUyLXFvDRnLMoo7T6O04Q83IzKDuDvPQ2S5clq+cEQXMvy/y  hex로 읽음 -> 유효하지 않음
✓ 정상
Wi6BuLpov8RndEfedUyLXFvDRnLMoo7T6O04Q83IzKDuDvPQ2S5clq+cEQXMvy/y  Base64로 읽음 -> 48바이트

제로 패딩이 실제 데이터 끝의 0x00을 삭제함

제로 패딩은 패딩과 데이터를 구별하지 못하므로, 실제로 0x00으로 끝나는 평문은 그 바이트를 잃습니다. 일반 텍스트가 아닌 데이터에는 PKCS#7을 사용하세요.

✗ 오류
제로 패딩: 61 62 00  -> 복호화 결과 61 62
✓ 정상
PKCS#7:    61 62 00  -> 복호화 결과 61 62 00

"SM4"가 어디서나 같은 모드라고 가정함

OpenSSL은 sm4를 CBC로 처리합니다. 반면 BouncyCastle은, 따라서 Hutool의 SmUtil.sm4(key)도, SM4를 ECB와 PKCS#7로 처리합니다. 둘 다 "그냥 SM4를 쓰는" 두 시스템이라도 모드가 서로 다를 수 있습니다.

✗ 오류
Java:    Cipher.getInstance("SM4")  -> ECB + PKCS#7
OpenSSL: openssl enc -sm4           -> CBC
✓ 정상
Java:    Cipher.getInstance("SM4/CBC/PKCS5Padding")
OpenSSL: openssl enc -sm4-cbc

한쪽은 GBK, 다른 쪽은 UTF-8 바이트로 암호화

Java의 getBytes()는 문자 집합을 지정하지 않으면 플랫폼 기본값을 쓰는데, 중국어 Windows의 JDK 17 이하에서는 GBK입니다. 그러면 같은 중국어 텍스트가 다른 암호문이 되고, 상대 쪽에서 복호화하면 글자가 깨집니다.

✗ 오류
"国密SM4 test".getBytes()  // 중국어 Windows JDK <= 17에서는 GBK
-> ECB 암호문 3188d06cf28db70092f8753cbd5ee518
✓ 정상
"国密SM4 test".getBytes(StandardCharsets.UTF_8)
-> ECB 암호문 d830308b0ae4fa7b9a2b5d59f7f65ca5

SM4 온라인 암호화가 필요한 경우

백엔드와 프런트엔드의 SM4 출력 맞추기
Java 서비스와 웹 클라이언트가 같은 텍스트로 서로 다른 암호문을 냅니다. 각 쪽을 해당 라이브러리 프리셋으로 여기서 재현하고, 어떤 파라미터가 다른지 확인하세요.
파트너 시스템에서 받은 암호문의 복호화 실패 디버깅
파트너가 보낸 SM4 암호문이 복호화되지 않습니다. 합의한 키, IV와 함께 붙여넣으면 진단 기능이 상대가 실제로 사용한 모드, 패딩, 인코딩을 찾아냅니다.
SM4 구현 검증
구현을 운영 데이터에 적용하기 전에, 이 페이지의 GB/T 32907 벡터로 코드를 테스트하고 CBC 왕복 결과를 비교하세요.
SM4 마이그레이션용 테스트 데이터 준비
시스템을 AES에서 SM4로 옮길 때, 여기서 키·IV·암호문 조합을 생성해 새 테스트의 픽스처로 사용하세요.
블록 암호 모드의 동작 관찰
같은 블록 두 개를 ECB와 CBC로 암호화하거나 틀린 IV로 복호화해 보고, 암호문과 출력이 어떻게 달라지는지 확인하세요.

SM4와 운영 모드의 동작 원리

블록 크기, 키 길이, 라운드 수
SM4는 128비트 키로 128비트 블록을 32라운드에 걸쳐 암호화합니다. 각 라운드는 32비트 워드에 8비트 S-box를 적용한 뒤, 그 워드와 워드를 네 가지로 순환 이동한 값을 XOR하는 선형 변환을 적용합니다. 복호화는 라운드 키를 역순으로 사용해 같은 32라운드를 실행합니다.
ECB: 블록마다 독립적으로 처리
ECB는 16바이트 블록을 각각 독립적으로 암호화합니다. IV가 필요 없지만 같은 평문 블록은 같은 암호문 블록이 되므로 데이터의 패턴이 그대로 보입니다. 입력이 16바이트의 배수가 아니면 패딩이 필요합니다.
CBC: 블록 연쇄와 IV
CBC는 각 평문 블록을 암호화하기 전에 직전 암호문 블록과 XOR하며, 첫 블록에는 IV를 사용합니다. IV는 첫 블록에만 관여하므로 IV가 틀리면 평문의 처음 16바이트만 정확히 깨지고 마지막 블록의 패딩은 온전히 남아, 오류가 전혀 나지 않는 경우가 많습니다.
CTR, CFB, OFB: 스트림 암호로 쓰는 SM4
이 모드들은 카운터나 피드백 값을 암호화한 결과를 데이터와 XOR하므로, 암호문 길이가 평문과 같고 패딩이 없습니다. CTR에서는 OpenSSL과 마찬가지로 16바이트 IV 전체를 하나의 128비트 빅엔디언 카운터로 증가시킵니다. IV가 틀리면 CTR과 OFB에서는 메시지 전체가 깨지지만, CFB에서는 첫 블록만 깨집니다.
패딩 규칙
PKCS#7은 값이 n인 바이트를 1~16개 덧붙이므로, 이미 블록의 정수 배인 메시지에도 블록 하나 분량의 패딩이 추가됩니다. 제로 패딩은 필요할 때만 0x00 바이트를 채우고, 복호화할 때 끝에 있는 0을 모두 제거합니다. 패딩 없음은 데이터를 그대로 두며, 블록을 꽉 채우지 못하는 입력은 거부합니다.

SM4 사용 모범 사례

새 설계에는 ECB를 선택하지 마십시오
ECB는 어떤 블록끼리 같은지를 노출합니다. 이미 ECB를 쓰는 기존 시스템과 맞춰야 하는 경우가 아니라면 CBC나 CTR을 사용하세요.
메시지마다 새 무작위 IV를 사용하세요
IV는 비밀이 아니지만 같은 키에서 반복되어서는 안 됩니다. 메시지마다 무작위로 생성하고, 암호문 옆에 함께 저장하거나 전송하세요.
암호문을 인증하세요
중국의 블록 암호 운영 모드 표준인 GB/T 17964-2021은 이 표준이 규정하는 모드가 기밀성을 보호할 뿐 무결성은 보호하지 않는다고 명시합니다. CBC에서는 IV의 한 바이트만 바꿔도 pay=100.00pay=900.00으로 바뀌고, 복호화는 여전히 성공합니다. HMAC 생성기 등으로 IV와 암호문에 대한 MAC을 계산하고, 복호화하기 전에 검증하세요.
모든 파라미터를 인터페이스 명세에 적으세요
"SM4로 암호화했다"는 명세가 아닙니다. 모드, 패딩, 키와 IV의 인코딩 방식, 평문 문자 집합, 암호문이 hex인지 Base64인지를 모두 적어 두세요.
실제 키를 웹 페이지와 소스 코드에 두지 마십시오
이 페이지는 테스트 키로만 사용하세요. 운영 환경 키는 키 관리 시스템이나 하드웨어 보안 모듈에 보관하고, 붙여넣거나 커밋하지 말고 런타임에 불러와야 합니다.

SM4 자주 묻는 질문

SM4 복호화에서 패딩 오류가 나거나 글자가 깨지는 이유는 무엇인가요?
복호화는 키 바이트, 모드, IV, 패딩, 그리고 암호문을 어떤 형식(hex 또는 Base64)으로 적었는지까지 암호화한 쪽과 모두 일치해야만 성공합니다. "bad decrypt", 패딩 예외, 알아볼 수 없는 문자열 같은 증상은 그중 무엇이 틀렸는지 알려 주지 않으며, 어떤 라이브러리는 오류 없이 빈 결과만 반환합니다. 그래도 암호문, 키, IV를 여기에 붙여넣어 보세요. 복호화가 실패하면 이 페이지는 암호문 인코딩, 키 형식, 모드, IV, 패딩의 모든 조합을 다시 시도합니다. 라이브러리가 경고 없이 16바이트로 잘라 낸 키와 GBK로 인코딩된 평문도 시도 대상에 들어갑니다. 그런 다음 읽을 수 있는 텍스트가 나오는 해석을 나열하고, PKCS#7 패딩 검증까지 통과한 해석에는 표시를 붙입니다. 처음 16바이트만 틀리게 나온다면 키와 모드는 맞고 IV가 틀린 것입니다.
SM4 키 길이는 얼마인가요? 256비트 키도 쓸 수 있나요?
SM4 키는 정확히 128비트, 즉 16바이트로 블록 크기와 같습니다. GB/T 32907이 정의하는 키 길이는 이것 하나뿐이며, 192비트나 256비트 SM4는 없습니다. 누군가 256비트 SM4 키를 요구한다면, 32자리 hex 문자열을 8비트짜리 문자 32개로 센 것은 아닌지 확인하세요. 16바이트는 hex 32자리로도, ASCII 문자 16개로도 쓸 수 있고, 이 둘을 혼동하는 것이 가장 흔한 키 오류입니다. 0123456789abcdeffedcba9876543210을 hex로 읽으면 16바이트지만, 같은 문자열을 텍스트로 읽으면 32바이트가 되어 거부됩니다. 키 입력란 옆의 형식 선택기와 바이트 카운터가 바로 이런 실수를 잡아내기 위해 있습니다.
SM4의 IV는 무엇이고, 길이는 얼마여야 하나요?
IV(초기화 벡터, initialization vector)는 CBC, CTR, CFB, OFB에서 첫 블록에 섞이는 16바이트 값이며, ECB는 IV를 쓰지 않습니다. 반드시 정확히 16바이트, 즉 hex 32자리 또는 ASCII 문자 16개여야 하므로, IV 길이 오류가 나면 32자리 hex 문자열을 32바이트 텍스트로 읽은 것은 아닌지 확인하세요. IV는 비밀이 아니지만 같은 키에서 반복되어서는 안 됩니다. 무작위로 생성해 암호문과 함께, 흔히 암호문 앞에 붙여서 보냅니다. CBC에서 IV가 틀리면 보통 오류 없이 처음 16바이트만 깨집니다. 일부 라이브러리는 IV를 주지 않으면 조용히 전부 0인 IV를 사용하고(sm-crypto-v2, Go의 tjfoc/gmsm), Java의 BouncyCastle은 무작위 IV를 생성합니다. 이때 그 IV를 암호문과 함께 저장하지 않으면 누구도 복호화할 수 없습니다.
SM4 ECB와 CBC의 차이는 무엇이고, 어느 쪽을 써야 하나요?
메시지마다 새로운 무작위 IV와 함께 CBC(또는 CTR)를 사용하세요. ECB는 같은 16바이트 블록을 같은 암호문 블록으로 암호화하므로, 데이터 속 반복 구조가 암호문에 그대로 드러납니다. ECB는 이미 ECB를 쓰고 있는 시스템과 연동할 때만 선택하세요. 두 모드 모두 변조를 탐지하지 못한다는 점에도 유의해야 합니다. 변조 여부가 중요하다면 HMAC 생성기 등으로 IV와 암호문에 대한 MAC도 함께 보내세요.
SM4 패딩은 PKCS5Padding, PKCS#7, 제로 패딩, 패딩 없음 중 무엇을 써야 하나요?
PKCS#7은 항상 1~16바이트를 덧붙이며 각 바이트에 덧붙인 바이트 수를 기록하므로, 받는 쪽에서 모호함 없이 제거할 수 있습니다. SM4처럼 블록이 16바이트인 블록 암호에서는 Java의 PKCS5Padding도 같은 패딩이며, BouncyCastle은 두 이름을 같은 코드 경로로 처리합니다. 제로 패딩은 다음 블록 경계까지만 0x00을 채웁니다. 복호화할 때 Hutool과 BouncyCastle은 끝에 붙은 0x00을 원래 데이터의 일부였던 0x00 바이트까지 전부 제거하지만, Python의 gmssl은 하나만 제거합니다. 패딩 없음은 입력 길이가 16바이트 블록의 정수 배여야 합니다. CTR, CFB, OFB는 스트림 모드라서 패딩을 전혀 쓰지 않습니다. 복호화한 텍스트 끝에 알 수 없는 공백, 네모 문자, 줄바꿈이 남아 있다면 패딩이 제거되지 않은 것입니다. PKCS#7로 패딩한 데이터를 패딩 없음으로 복호화하면 끝에 값이 n인 바이트가 n개 남습니다(0x09, 0x0A, 0x0D는 탭과 줄바꿈으로 보입니다). 출력을 Hex로 바꿔 마지막 블록을 확인하세요.
SM4 암호문 길이는 얼마이며, 암호문만 보고 모드를 알 수 있나요?
바이트 단위로 세세요. ECB나 CBC에서 PKCS#7을 쓰면 평문 길이는 다음 16의 배수로 올림되고, 이미 16의 배수인 메시지에는 블록이 하나 더 붙습니다. 5바이트나 15바이트는 16바이트가 되고, 16바이트는 32바이트가 됩니다. 제로 패딩은 다음 16의 배수까지만 채우고, 패딩 없음은 길이를 그대로 유지하며, CTR·CFB·OFB 암호문은 평문과 길이가 정확히 같습니다. Hex는 바이트 수의 두 배이고 Base64는 4 × ⌈바이트 수 / 3⌉ 자이므로, 16바이트는 24자, 32바이트는 44자, 64바이트는 88자입니다. IV를 앞에 붙여 보낸다면 16바이트를 더하세요. 암호문만으로는 모드를 알 수 없지만 두 가지 단서가 도움이 됩니다. 길이가 16의 배수가 아니면 패딩을 쓴 ECB나 CBC일 가능성은 사실상 없고, 똑같은 16바이트 블록이 두 개 있으면 ECB일 가능성이 높습니다. 확실하지 않다면 복호화 탭에 붙여넣으세요. 자동 진단이 여러 모드를 대신 시도합니다.
SM4는 매번 같은 암호문을 출력하나요? 다른 도구와 결과가 다른 이유는 무엇인가요?
ECB, 또는 IV를 고정한 모드는 같은 키와 평문에 대해 매번 같은 암호문을 출력합니다. 실행할 때마다 새 무작위 IV를 쓰면 출력이 매번 달라지며, 그것이 정상입니다. 그 밖에는 모드, 패딩, 키를 hex로 읽었는지 텍스트로 읽었는지, 평문을 어떻게 인코딩했는지(대부분의 코드는 UTF-8이지만, 오래된 Java 코드가 중국어 Windows에서 getBytes()를 호출하면 GBK), 결과를 어떻게 출력했는지(Base64, 소문자 hex, 대문자 hex)를 비교하세요. 설정이 같고 IV가 고정되어 있다면 올바른 구현 두 개는 똑같은 결과를 냅니다. 어느 한 도구가 의심스럽다면 먼저 두 도구를 모두 GB/T 32907 테스트 벡터로 검증하세요.
직접 구현한 SM4가 올바른지 어떻게 확인하나요?
GB/T 32907-2016 부록 A의 두 벡터로 시작하세요. 키와 평문이 모두 0123456789abcdeffedcba9876543210일 때, 1회 암호화하면 681edf34d206965e86b3e94f536e4246, 100만 회 연쇄 암호화하면 595298c7c6fd271f0402f804c33d3f66이 나와야 합니다. 이 벡터는 블록 암호 자체만 검증하므로, 다음으로 고정된 키와 IV로 텍스트를 CBC 모드로 암호화해 이 페이지의 결과나 이 페이지가 보여 주는 OpenSSL 명령의 결과와 비교하세요. 이 페이지의 엔진은 두 벡터로 테스트되었고, 다섯 가지 모드 모두에서 OpenSSL 3과 교차 검증되었습니다.
OpenSSL로 SM4 암호화와 복호화를 할 수 있나요?
네. OpenSSL 3은 ECB, CBC, CFB, OFB, CTR 모드의 SM4를 지원합니다. openssl enc -sm4-cbc -K <32 hex digits> -iv <32 hex digits> 형식으로 사용합니다. -K는 hex로 된 원시 키를 받으므로 비밀번호가 개입하지 않고, -nopad는 PKCS#7을 끄며, -base64 -A는 한 줄짜리 Base64를 읽거나 씁니다. 두 가지를 주의하세요. 그냥 -sm4라고 쓰면 CBC를 뜻하고, 길이가 틀린 -K 값은 경고만 표시된 채 잘리거나 0으로 채워집니다. 이 페이지의 OpenSSL 패널은 현재 설정으로 명령을 구성합니다. openssl enc에는 제로 패딩이 없으므로, 그 경우 패널은 결과가 일치하지 않을 명령을 출력하는 대신 그 사실을 알려 줍니다.
Java(Hutool)나 JavaScript(sm-crypto)에서 나온 SM4 암호문은 어떻게 복호화하나요?
먼저 상대 쪽이 실제로 어떤 모드와 패딩을 쓰는지 확인하세요. 코드에 명시되어 있지 않은 경우가 많습니다. Hutool의 SmUtil.sm4(key)SM4라는 이름만 넘기고, BouncyCastle은 나머지를 ECB와 PKCS#7(Java의 PKCS5Padding)로 채웁니다. SM4/CBC/PKCS5Padding처럼 전체 문자열을 지정해야만 CBC가 됩니다. JavaScript의 sm-crypto 역시 기본값이 ECB이고, 키를 32자리 hex 문자열로 받으며 소문자 hex를 출력합니다. 반면 gm-crypt는 기본값이 CBC이고, 16자 텍스트 키를 받으며 Base64를 출력합니다. 그다음 평문의 문자 집합을 확인하세요. Hutool의 문자열 메서드는 항상 UTF-8을 쓰지만, 중국어 Windows의 JDK 17 이하에서 인자 없는 getBytes()는 GBK를 뜻할 수 있고, 그러면 암호문이 달라집니다. 라이브러리 기본값 맞추기에서 라이브러리를 고르면 이 설정이 한 번에 지정되며, 직접 입력해도 됩니다. 확실하지 않은 항목이 있다면 일단 암호문을 붙여넣으세요. 자동 진단이 모드, 패딩, IV, 인코딩의 조합을 시도합니다.
SM4는 안전한가요? 제 데이터가 업로드되나요?
알고리즘으로서 SM4는 128비트 키와 32라운드를 사용하며, RFC 8998(2021)은 작성 시점 기준으로 SM4에 알려진 약한 키나 보안 문제가 없다고 밝히고 있습니다. 실질적인 위험은 사용 방식에서 생깁니다. ECB는 패턴을 노출하고, CBC는 변조를 탐지하지 못합니다. 이 페이지는 아무것도 업로드하지 않습니다. 브라우저에는 SM4가 내장되어 있지 않으므로 이 페이지는 자체 SM4 구현을 싣고 로컬에서 실행합니다. 네트워크 패널을 열어 요청이 하나도 나가지 않는 것을 확인하거나, 인터넷 연결을 끊은 채 계속 사용해 볼 수 있습니다. 따라서 테스트 데이터, 디버깅, 학습 용도로는 문제없습니다. 그렇다고 웹 페이지가 운영 환경의 키를 다룰 곳이 되는 것은 아닙니다. 그런 키는 어떤 웹사이트의 텍스트 상자도 아닌, 키 관리 시스템이나 하드웨어 보안 모듈에 두어야 합니다.
SM4와 AES의 차이는 무엇인가요?
둘 다 128비트 블록을 쓰는 블록 암호이고, 모드와 패딩도 똑같이 동작합니다. 그래서 SM4 상호 운용 버그는 AES 버그와 증상이 똑같습니다. SM4는 32라운드를 거치고 키 길이는 128비트 하나뿐입니다. AES-128은 10라운드이며, AES에는 192비트와 256비트 키도 있습니다. SM4는 중국 국가 표준 GB/T 32907-2016이고, 2021년부터 AES와 나란히 국제 표준 ISO/IEC 18033-3에 포함되었으며, 중국 상용 암호 사용이 요구되는 곳에서 쓰입니다. AES는 NIST 표준 FIPS 197입니다. AES가 필요하다면 AES 암호화기를 사용하세요.

AES 복호화 도구 — OpenSSL·CryptoJS 호환

보안 도구

온라인 AES 복호화 — GCM/CBC/CTR, 암호 문구 또는 원시 키, OpenSSL·CryptoJS "U2FsdGVkX1" 형식 자동 인식. 브라우저에서만 실행되며 키는 유출되지 않습니다.

AES 암호화 도구 — GCM, CBC, CTR 모드

보안 도구

무료 온라인 AES 암호화 도구 — AES-128/192/256, GCM/CBC/CTR, 암호 문구(PBKDF2) 또는 원시 키. 브라우저에서만 실행되고 서버 업로드는 없습니다.

Bcrypt 해시 생성 및 검증 도구

보안 도구

온라인으로 bcrypt 비밀번호 해시를 생성·검증하세요 — 조절 가능한 비용 인자, $2b$/$2a$/$2y$ 접두사 지원. 100% 브라우저에서 실행, 비밀번호는 업로드되지 않습니다.

CRC 순환 중복 검사 계산기

보안 도구

16진수나 텍스트에서 CRC-8·CRC-16·CRC-32 변형 63개를 계산하는 온라인 도구. 맞지 않는 체크섬을 역조회 칸에 넣으면 MODBUS 등 어느 변형인지 알려 줍니다.

HMAC 생성기 및 서명 검증 도구

보안 도구

무료 온라인 HMAC 생성·검증 도구. Text/Hex/Base64 키로 HMAC-SHA256/SHA1/SHA384/SHA512를 Hex/Base64/Base64URL로 출력. 100% 브라우저 실행, 키 유출 없음.

JWT 디코더 (JWT Decoder)

보안 도구

무료 JWT 디코더로 JWT 토큰을 온라인에서 즉시 디코딩. 헤더, 페이로드, 서명, 만료, 클레임 확인. 100% 브라우저 기반 — 토큰이 기기를 떠나지 않음. 가입·추적 없음.