본문으로 건너뛰기

암호화(cryptography) 사용법 (syn.$c)

개요

syn.$c는 base64/UTF-8 인코딩, SHA 해시, HMAC 서명, RSA/AES 암호화, LZString 압축 등 브라우저에서 필요한 암호화·인코딩 기능을 제공합니다. 대부분의 기능은 브라우저 WebCrypto(SubtleCrypto) API를 사용하며, 비동기(Promise) 방식으로 동작합니다. sha256(), encrypt(), decrypt()처럼 WebCrypto 없이 동작하는 동기 방식의 경량 구현도 함께 제공됩니다.

로드 방법

syn.js가 로드되면 전역에 syn.$c(원본 이름: syn.$cryptography)로 즉시 사용할 수 있습니다.

빠른 시작

// 문자열 해시
const hash = syn.$c.sha256('hello world');

// base64 인코딩/디코딩
const encoded = syn.$c.base64Encode('안녕하세요');
const decoded = syn.$c.base64Decode(encoded);

// HMAC 서명 생성 (비동기)
syn.$c.generateHMAC('secret-key', 'hello world').then((signature) => {
console.log(signature);
});

주요 시나리오

1. 간단한 해시/인코딩

sha256()은 동기 함수라 바로 결과를 받을 수 있고, sha()는 WebCrypto digest를 사용해 SHA-1/SHA-256/SHA-384/SHA-512 등 다양한 알고리즘을 비동기로 계산합니다.

const hash256 = syn.$c.sha256('hello world');

syn.$c.sha('hello world', 'SHA-256').then((hash) => {
console.log(hash);
});

2. HMAC 서명 생성/검증

서버와 클라이언트가 공유한 키로 메시지 위변조 여부를 검증할 때 사용합니다.

syn.$c.generateHMAC('handstack', 'hello world').then((signature) => {
return syn.$c.verifyHMAC('handstack', 'hello world', signature);
}).then((isValid) => {
console.log(isValid); // true
});

3. RSA 키 생성과 암/복호화

공개키로 암호화하고 개인키로 복호화하는 비대칭 암호화 흐름입니다. 키를 PEM 형식으로 내보내고(export) 다시 가져올(import) 수 있습니다.

syn.$c.generateRSAKey().then((cryptoKey) => {
return syn.$c.rsaEncode('hello world', cryptoKey.publicKey).then((encrypted) => {
return syn.$c.rsaDecode(encrypted, cryptoKey.privateKey);
});
}).then((decrypted) => {
console.log(decrypted); // hello world
});

4. AES 대칭키 암호화

aesEncode()는 IV(초기화 벡터)와 암호문을 함께 반환하며, 복호화 시 동일한 키와 IV가 필요합니다.

syn.$c.aesEncode('hello world', 'my-key').then((result) => {
// result = { iv, encrypted }
return syn.$c.aesDecode(result, 'my-key');
}).then((decrypted) => {
console.log(decrypted); // hello world
});

5. 경량 대칭 암호화(encrypt/decrypt)

WebCrypto 없이도 사용할 수 있는 간단한 문자열 암호화입니다. 세션 스토리지에 저장할 값을 가볍게 가리는 용도로 적합합니다.

const encrypted = syn.$c.encrypt('hello world', 'my-key');
const decrypted = syn.$c.decrypt(encrypted, 'my-key');

6. LZString 압축

긴 문자열을 URL 파라미터나 localStorage에 저장하기 전에 압축할 때 사용합니다. 압축 결과 형식(base64/UTF-16/URI 컴포넌트)에 맞는 해제 함수를 사용해야 합니다.

const compressed = syn.$c.LZString.compressToBase64('반복되는 긴 문자열...');
const original = syn.$c.LZString.decompressFromBase64(compressed);

실전 예제 페이지

/sample/syn/cryptography.html 예제에서 다음 항목을 실습할 수 있습니다.

  • isWebCryptoSupported, base64Encode/base64Decode, utf8Encode/utf8Decode
  • padKey, convertToBuffer
  • sha, sha256
  • generateHMAC/verifyHMAC
  • generateRSAKey/exportCryptoKey/importCryptoKey, rsaEncode/rsaDecode
  • generateIV, aesEncode/aesDecode
  • encrypt/decrypt
  • LZString의 compress/compressToBase64/compressToUTF16/compressToEncodedURIComponent 및 대응하는 decompress 계열 함수

주의 사항

  • WebCrypto 기반 API(generateHMAC, generateRSAKey, exportCryptoKey, importCryptoKey, rsaEncode, rsaDecode, aesEncode, aesDecode, sha)는 모두 비동기(Promise)이며, HTTPS(또는 localhost)가 아닌 환경에서는 context.crypto.subtle이 없어 동작하지 않을 수 있습니다. 사용 전 isWebCryptoSupported()로 확인하는 것이 안전합니다.
  • aesDecode()는 암호화 시 사용한 것과 동일한 key, algorithm, keyLength를 전달해야 하며, encryptedDataivencrypted 값이 모두 있어야 합니다.
  • padKey(), convertToBuffer(), generateIV()는 다른 메서드 내부에서 사용되는 저수준 헬퍼이지만 syn.$c를 통해 외부에서도 호출할 수 있습니다.
  • 소스에는 devicePlatform === 'node'일 때 Buffer를 사용하는 Node.js 전용 경로가 base64Encode/base64Decode에 별도로 구현되어 있습니다. 브라우저 데모 페이지에서는 이 경로가 실행되지 않지만, 서버 사이드(Node) 스크립트에서 동일한 API를 재사용할 수 있다는 점을 참고하세요.
  • encrypt()/decrypt()는 WebCrypto를 사용하지 않는 간단한 치환 방식이므로, 보안이 중요한 데이터에는 AES/RSA 계열 API를 사용하는 것이 좋습니다.

관련 모듈

  • API 상세는 아래 API 참조 섹션을 확인하세요.

API 참조

모듈 정보

항목내용
전역 별칭syn.$c (원본: context.$cryptography)
소스 위치2.Modules/wwwroot/wwwroot/js/syn.js (약 1272~2151번째 줄)
예제 페이지/sample/syn/cryptography.html
의존 모듈syn.$string($string.toBoolean), syn.$l(eventLog, stringToArrayBuffer), 브라우저 WebCrypto(crypto.subtle)

속성

$cryptography는 별도로 노출되는 데이터 속성이 없으며, 모든 기능은 메서드로 제공됩니다. (내부적으로 LZString이라는 하위 네임스페이스 객체를 property로 가지고 있으며, 이 객체가 제공하는 압축/해제 함수는 메서드 목록에서 다룹니다.)

메서드

syn.$c.isWebCryptoSupported()

  • 설명: 현재 실행 환경에서 crypto.subtle(WebCrypto)을 사용할 수 있는지 여부를 반환합니다.
  • 매개변수: 없음
  • 반환값: boolean — WebCrypto 지원 여부
  • 예시
    if (syn.$c.isWebCryptoSupported()) {
    syn.$c.generateRSAKey().then((cryptoKey) => { /* ... */ });
    }

syn.$c.base64Encode(val)

  • 설명: 문자열을 base64 문자열로 인코딩합니다. devicePlatform === 'node'인 경우 Node Buffer를 사용합니다.
  • 매개변수
    이름타입필수설명
    valstringY인코딩할 원본 문자열
  • 반환값: string — base64 인코딩 문자열 (실패 시 null)
  • 예시
    const encoded = syn.$c.base64Encode('hello world');

syn.$c.base64Decode(val)

  • 설명: base64 문자열을 원본 문자열로 디코딩합니다.
  • 매개변수
    이름타입필수설명
    valstringY디코딩할 base64 문자열
  • 반환값: string — 디코딩된 원본 문자열 (실패 시 null)
  • 예시
    const decoded = syn.$c.base64Decode(encoded);

syn.$c.utf8Encode(plainString)

  • 설명: 문자열을 UTF-8 바이트 배열(Uint8Array)로 인코딩합니다. 문자열이 아닌 값을 전달하면 TypeError를 발생시킵니다.
  • 매개변수
    이름타입필수설명
    plainStringstringY인코딩할 문자열
  • 반환값: Uint8Array — UTF-8 바이트 배열 (실패 시 null)
  • 예시
    const bytes = syn.$c.utf8Encode('안녕하세요');

syn.$c.utf8Decode(encodeString)

  • 설명: 콤마로 구분된 UTF-8 바이트 코드 문자열(예: "236,149,136")을 원본 문자열로 디코딩합니다. 문자열이 아닌 값을 전달하면 TypeError를 발생시킵니다.
  • 매개변수
    이름타입필수설명
    encodeStringstringY콤마로 구분된 바이트 코드 문자열
  • 반환값: string — 디코딩된 문자열 (실패 시 null)
  • 예시
    const text = syn.$c.utf8Decode(bytes.join(','));

syn.$c.convertToBuffer(values)

  • 설명: 숫자 배열을 ArrayBuffer로 변환합니다. 다른 인코딩/디코딩 메서드 내부에서 사용되는 저수준 헬퍼입니다.
  • 매개변수
    이름타입필수설명
    valuesnumber[]Y0~255 범위의 바이트 값 배열
  • 반환값: ArrayBuffer
  • 예시
    const buffer = syn.$c.convertToBuffer([104, 101, 108, 108, 111]);

syn.$c.padKey(key, length)

  • 설명: 키 문자열을 지정된 길이(byte)로 잘라내거나 0으로 채워서 고정 길이의 Uint8Array로 반환합니다. AES 키/IV 생성에 내부적으로 사용됩니다.
  • 매개변수
    이름타입필수설명
    keystringY원본 키 문자열
    lengthnumberY결과 바이트 길이
  • 반환값: Uint8Array — 지정된 길이로 맞춰진 키 (key가 문자열이 아니면 null)
  • 예시
    const paddedKey = syn.$c.padKey('my-key', 16);

syn.$c.generateHMAC(key, message)

  • 설명: HMAC-SHA256 알고리즘으로 메시지의 서명을 생성합니다.
  • 매개변수
    이름타입필수설명
    keystringY서명 생성에 사용할 키
    messagestringY서명할 메시지
  • 반환값: Promise<string> — 16진수 문자열 형태의 HMAC 서명
  • 예시
    syn.$c.generateHMAC('handstack', 'hello world').then((signature) => {
    console.log(signature);
    });

syn.$c.verifyHMAC(key, message, signature)

  • 설명: 주어진 서명이 key/message로부터 생성한 HMAC 서명과 일치하는지 검증합니다.
  • 매개변수
    이름타입필수설명
    keystringY서명 생성에 사용한 키
    messagestringY서명 대상 메시지
    signaturestringY검증할 HMAC 서명(16진수 문자열)
  • 반환값: Promise<boolean> — 서명 일치 여부
  • 예시
    syn.$c.verifyHMAC('handstack', 'hello world', signature).then((isValid) => {
    console.log(isValid);
    });

syn.$c.generateRSAKey()

  • 설명: RSA-OAEP(2048bit, SHA-256) 공개키/개인키 쌍을 생성합니다.
  • 매개변수: 없음
  • 반환값: Promise<CryptoKeyPair>{ publicKey, privateKey } 형태의 CryptoKey
  • 예시
    syn.$c.generateRSAKey().then((cryptoKey) => {
    console.log(cryptoKey.publicKey, cryptoKey.privateKey);
    });

syn.$c.exportCryptoKey(cryptoKey, isPublic)

  • 설명: CryptoKey를 PEM(SPKI/PKCS8) 형식의 문자열로 내보냅니다.
  • 매개변수
    이름타입필수설명
    cryptoKeyCryptoKeyY내보낼 키
    isPublicbooleanYtrue면 공개키(SPKI), false면 개인키(PKCS8)
  • 반환값: Promise<string>-----BEGIN PUBLIC/PRIVATE KEY----- 형식의 PEM 문자열
  • 예시
    syn.$c.exportCryptoKey(cryptoKey.publicKey, true).then((pem) => console.log(pem));

syn.$c.importCryptoKey(pem, isPublic)

  • 설명: PEM 형식 문자열을 다시 CryptoKey로 가져옵니다.
  • 매개변수
    이름타입필수설명
    pemstringYPEM 형식의 키 문자열
    isPublicbooleanYtrue면 공개키(SPKI, encrypt 용도), false면 개인키(PKCS8, decrypt 용도)
  • 반환값: Promise<CryptoKey>
  • 예시
    syn.$c.importCryptoKey(pemString, true).then((publicKey) => { /* ... */ });

syn.$c.rsaEncode(text, publicKey)

  • 설명: RSA-OAEP 공개키로 문자열을 암호화하고 base64 문자열로 반환합니다.
  • 매개변수
    이름타입필수설명
    textstringY암호화할 원문
    publicKeyCryptoKeyYRSA 공개키
  • 반환값: Promise<string> — base64 인코딩된 암호문
  • 예시
    syn.$c.rsaEncode('hello world', cryptoKey.publicKey).then((encrypted) => { /* ... */ });

syn.$c.rsaDecode(encryptedData, privateKey)

  • 설명: rsaEncode()로 암호화된 base64 문자열을 RSA-OAEP 개인키로 복호화합니다.
  • 매개변수
    이름타입필수설명
    encryptedDatastringYbase64 인코딩된 암호문
    privateKeyCryptoKeyYRSA 개인키
  • 반환값: Promise<string> — 복호화된 원문
  • 예시
    syn.$c.rsaDecode(encrypted, cryptoKey.privateKey).then((decrypted) => { /* ... */ });

syn.$c.generateIV(key, ivLength)

  • 설명: AES 암호화에 사용할 초기화 벡터(IV)를 생성합니다. key'$RANDOM$'(대소문자 무관)이면 난수 IV를 생성하고, 그 외에는 padKey()로 고정된 IV를 만듭니다.
  • 매개변수
    이름타입필수설명
    keystringNIV 생성에 사용할 키 또는 '$RANDOM$'
    ivLengthnumberNIV 길이(byte), 기본값 16
  • 반환값: Uint8Array — 생성된 IV
  • 예시
    const iv = syn.$c.generateIV('$RANDOM$', 12);

syn.$c.aesEncode(text, key, algorithm, keyLength)

  • 설명: AES(CBC 또는 GCM) 알고리즘으로 문자열을 암호화합니다.
  • 매개변수
    이름타입필수설명
    textstringY암호화할 원문
    keystringN암호화 키, 기본값 빈 문자열
    algorithmstringN'AES-CBC'(기본) 또는 'AES-GCM'
    keyLengthnumberN128 또는 256(bit), 기본값 256
  • 반환값: Promise<{ iv: string, encrypted: string }> — base64로 인코딩된 IV와 암호문
  • 예시
    syn.$c.aesEncode('hello world', 'my-key').then((result) => { /* { iv, encrypted } */ });

syn.$c.aesDecode(encryptedData, key, algorithm, keyLength)

  • 설명: aesEncode()로 생성된 결과를 복호화합니다. 암호화 시 사용한 것과 동일한 key/algorithm/keyLength를 전달해야 합니다.
  • 매개변수
    이름타입필수설명
    encryptedDataiv, encrypted 속성 객체YaesEncode() 결과 객체
    keystringN암호화 시 사용한 키
    algorithmstringN'AES-CBC'(기본) 또는 'AES-GCM'
    keyLengthnumberN128 또는 256(bit), 기본값 256
  • 반환값: Promise<string> — 복호화된 원문 (encryptedData가 유효하지 않으면 null)
  • 예시
    syn.$c.aesDecode(result, 'my-key').then((decrypted) => { /* ... */ });

syn.$c.sha(message, algorithms)

  • 설명: WebCrypto digest를 사용해 지정한 알고리즘으로 메시지의 해시 값을 계산합니다.
  • 매개변수
    이름타입필수설명
    messagestringY해시를 계산할 문자열
    algorithmsstringN'SHA-1'(기본), 'SHA-256', 'SHA-384', 'SHA-512'
  • 반환값: Promise<string> — 16진수 문자열 형태의 해시 값
  • 예시
    syn.$c.sha('hello world', 'SHA-256').then((hash) => console.log(hash));

syn.$c.sha256(s)

  • 설명: 순수 자바스크립트로 구현된 SHA-256 해시 함수로, WebCrypto 없이 동기적으로 결과를 반환합니다.
  • 매개변수
    이름타입필수설명
    sstringY해시를 계산할 문자열
  • 반환값: string — 16진수 문자열 형태의 SHA-256 해시 값
  • 예시
    const hash = syn.$c.sha256('hello world');

syn.$c.encrypt(value, key)

  • 설명: 문자 코드 치환 방식의 경량 대칭 암호화를 수행하고 URI 컴포넌트로 인코딩된 base64 문자열을 반환합니다. WebCrypto가 없어도 사용할 수 있습니다.
  • 매개변수
    이름타입필수설명
    valueanyY암호화할 값(문자열로 변환되어 처리됨)
    keystringN암호화 키, 생략 시 내부 기본 키 사용
  • 반환값: string — 암호화된 문자열 (valueundefined/null이면 null)
  • 예시
    const encrypted = syn.$c.encrypt('hello world', 'my-key');

syn.$c.decrypt(value, key)

  • 설명: encrypt()로 암호화된 문자열을 원래 값으로 복호화합니다. key가 일치하지 않으면 빈 문자열을 반환합니다.
  • 매개변수
    이름타입필수설명
    valuestringYencrypt()로 암호화된 문자열
    keystringN암호화 시 사용한 키
  • 반환값: string — 복호화된 원문 (형식이 올바르지 않으면 null)
  • 예시
    const decrypted = syn.$c.decrypt(encrypted, 'my-key');

syn.$c.LZString.compress(uncompressed)

  • 설명: 문자열을 LZString 알고리즘으로 압축하여 임의 문자(16bit) 코드 문자열로 반환합니다.
  • 매개변수
    이름타입필수설명
    uncompressedstringY압축할 원본 문자열
  • 반환값: string — 압축된 문자열
  • 예시
    const compressed = syn.$c.LZString.compress('반복되는 긴 문자열...');

syn.$c.LZString.compressToBase64(input) / decompressFromBase64(input)

  • 설명: 문자열을 압축해 base64 alphabet 기반 문자열로 인코딩하거나, 그 결과를 원래 문자열로 해제합니다.
  • 매개변수
    이름타입필수설명
    inputstringY압축할 원본 문자열 또는 압축 해제할 base64 문자열
  • 반환값: string
  • 예시
    const compressed = syn.$c.LZString.compressToBase64('반복되는 긴 문자열...');
    const original = syn.$c.LZString.decompressFromBase64(compressed);

syn.$c.LZString.compressToUTF16(input) / decompressFromUTF16(compressed)

  • 설명: 문자열을 압축해 UTF-16 안전 문자열로 인코딩하거나, 그 결과를 원래 문자열로 해제합니다. localStorage처럼 UTF-16 문자열을 저장하는 저장소에 적합합니다.
  • 매개변수
    이름타입필수설명
    input / compressedstringY압축할 원본 문자열 또는 압축 해제할 UTF-16 문자열
  • 반환값: string
  • 예시
    const compressed = syn.$c.LZString.compressToUTF16('반복되는 긴 문자열...');
    const original = syn.$c.LZString.decompressFromUTF16(compressed);

syn.$c.LZString.compressToUint8Array(uncompressed) / decompressFromUint8Array(compressed)

  • 설명: 문자열을 압축해 Uint8Array로 반환하거나, Uint8Array를 원래 문자열로 해제합니다. 바이너리 저장소나 전송에 적합합니다.
  • 매개변수
    이름타입필수설명
    uncompressed / compressedstring | Uint8ArrayY압축할 문자열 또는 압축 해제할 Uint8Array
  • 반환값: Uint8Array 또는 string
  • 예시
    const buffer = syn.$c.LZString.compressToUint8Array('반복되는 긴 문자열...');
    const original = syn.$c.LZString.decompressFromUint8Array(buffer);

syn.$c.LZString.compressToEncodedURIComponent(input) / decompressFromEncodedURIComponent(input)

  • 설명: 문자열을 압축해 URL 쿼리 파라미터로 바로 사용할 수 있는 URI-safe 문자열로 인코딩하거나, 그 결과를 원래 문자열로 해제합니다.
  • 매개변수
    이름타입필수설명
    inputstringY압축할 원본 문자열 또는 압축 해제할 URI-safe 문자열
  • 반환값: string
  • 예시
    const compressed = syn.$c.LZString.compressToEncodedURIComponent('반복되는 긴 문자열...');
    location.search = `?data=${compressed}`;