지급대행 암호화/복호화 오류
토스 환경: 라이브 (X), 테스트 (O), 개별 상점 보안키는 복사해서 사용하고 있습니다
개발환경 : windows 10, python 3.13.1
- 사용중인 API -> 셀러 등록
- 오류 상황
- 사용한 python 샘플 코드
- 복호화 시 python으로 안되서 사용한 node.js 샘플 코드는 다음과 같습니다
https://api.tosspayments.com/v2/sellers
# Headers
# Content-Type: text/plain
# TossPayments-api-security-mode: ENCRYPTION
# Authorization: Basic ...
https://api.tosspayments.com/v2/sellers
# Headers
# Content-Type: text/plain
# TossPayments-api-security-mode: ENCRYPTION
# Authorization: Basic ...
"""
암호화하면 텍스트는 나오고 복호화에서 cryptography.exceptions.InvalidTag 오류가 계속 나는거 보니 암호화도 잘 됐는지 의문인 상태입니다
node.js로도 해보고 다른 라이브러리도 써봤는데 동일한 오류가 계속 반복해서 나오고 있습니다
키 길이 64, hex 길이 32인 것도 확인했는데 어떤게 문제인걸까요?
"""
# 추가) Postman에서 ENCRYPTION 모드 헤더를 뺴고 보내보면 다음과 같은 응답이 옵니다
error = {
"version": "2022-11-16",
"traceId": "3ffd277fc1daf32c0f60390d81b95340",
"entityBody": null,
"entityType": null,
"error": {
"code": "INVALID_ENCRYPTION",
"message": "Invalid encryption format."
}
}
"""
암호화하면 텍스트는 나오고 복호화에서 cryptography.exceptions.InvalidTag 오류가 계속 나는거 보니 암호화도 잘 됐는지 의문인 상태입니다
node.js로도 해보고 다른 라이브러리도 써봤는데 동일한 오류가 계속 반복해서 나오고 있습니다
키 길이 64, hex 길이 32인 것도 확인했는데 어떤게 문제인걸까요?
"""
# 추가) Postman에서 ENCRYPTION 모드 헤더를 뺴고 보내보면 다음과 같은 응답이 옵니다
error = {
"version": "2022-11-16",
"traceId": "3ffd277fc1daf32c0f60390d81b95340",
"entityBody": null,
"entityType": null,
"error": {
"code": "INVALID_ENCRYPTION",
"message": "Invalid encryption format."
}
}
# pip install Authlib
# python version: 3.13.1
import binascii
import uuid
from datetime import datetime
from authlib.jose import JsonWebEncryption
target = {
"refSellerId": "test_id_1",
"businessType": "INDIVIDUAL",
"individual": {
"email": "email@email.com",
"name": "테스트",
"phone": "01011112222",
},
"account": {
"accountNumber": "12312312312312",
"bankCode": "90",
"holderName": "테스트",
},
}
def hexDecode(hex_key):
return binascii.unhexlify(hex_key)
def encrypt(target, hex_key):
# 보안 키 바이트로 전환
key = binascii.unhexlify(hex_key)
# JWE 헤더 생성
headers = {
"alg": "dir",
"enc": "A256GCM",
"iat": datetime.now().astimezone().isoformat(),
"nonce": str(uuid.uuid4()),
}
# Request Body 암호화
jwe = JsonWebEncryption()
encrypted = jwe.serialize_compact(headers, target.encode("utf-8"), key)
return encrypted
def decrypt(encrypted_jwe, hex_key):
# 보안 키 바이트로 전환
key = hexDecode(hex_key)
# JWE 응답 복호화
jwe = JsonWebEncryption()
decrypted = jwe.deserialize_compact(encrypted_jwe, key)
return decrypted["payload"].decode("utf-8")
# pip install Authlib
# python version: 3.13.1
import binascii
import uuid
from datetime import datetime
from authlib.jose import JsonWebEncryption
target = {
"refSellerId": "test_id_1",
"businessType": "INDIVIDUAL",
"individual": {
"email": "email@email.com",
"name": "테스트",
"phone": "01011112222",
},
"account": {
"accountNumber": "12312312312312",
"bankCode": "90",
"holderName": "테스트",
},
}
def hexDecode(hex_key):
return binascii.unhexlify(hex_key)
def encrypt(target, hex_key):
# 보안 키 바이트로 전환
key = binascii.unhexlify(hex_key)
# JWE 헤더 생성
headers = {
"alg": "dir",
"enc": "A256GCM",
"iat": datetime.now().astimezone().isoformat(),
"nonce": str(uuid.uuid4()),
}
# Request Body 암호화
jwe = JsonWebEncryption()
encrypted = jwe.serialize_compact(headers, target.encode("utf-8"), key)
return encrypted
def decrypt(encrypted_jwe, hex_key):
# 보안 키 바이트로 전환
key = hexDecode(hex_key)
# JWE 응답 복호화
jwe = JsonWebEncryption()
decrypted = jwe.deserialize_compact(encrypted_jwe, key)
return decrypted["payload"].decode("utf-8")
// yarn add jose
// node version: 22.13.1
// jose version: 6.1.0
import * as jose from "jose";
async function decryptJwe(payload: any) {
const securityText = process.env.KEY!;
const securityBuffer = Buffer.from(securityText, "hex");
const securityKey = new Uint8Array(securityBuffer);
const decrypted = await jose.compactDecrypt(payload, securityKey);
console.log("decrypted => ", decrypted);
const plainText = new TextDecoder().decode(decrypted.plaintext);
const object = JSON.parse(plainText);
console.log("object => ", object);
return decrypted;
}
// yarn add jose
// node version: 22.13.1
// jose version: 6.1.0
import * as jose from "jose";
async function decryptJwe(payload: any) {
const securityText = process.env.KEY!;
const securityBuffer = Buffer.from(securityText, "hex");
const securityKey = new Uint8Array(securityBuffer);
const decrypted = await jose.compactDecrypt(payload, securityKey);
console.log("decrypted => ", decrypted);
const plainText = new TextDecoder().decode(decrypted.plaintext);
const object = JSON.parse(plainText);
console.log("object => ", object);
return decrypted;
}
6 Replies
⏳ 잠시만 기다려주세요! 곧 답변드리겠습니다
오류 문의일 경우 아래 정보를 미리 전달해주시면, 빠른 답변에 도움이 됩니다.
- 주문번호(orderId) :
- 문의 내용 :
(img를 함께 첨부해주시면 도움이됩니다)
* 계약관련 내용은 1544-7772로 문의주세요.
* 주말/공휴일에는 답변이 늦을 수 있어요.
우선 위에 공유주신 traceId 는 개발연동 테스트 상점키로 하신것 같네요.
지급대행은 계약된 상점ID 라이브키/테스트키로 테스트하실 수 있습니다.
계약하신 가맹점이시라면 테스트키로 해보시고 오류 발생하면 traceId 를 남겨주세요.
"traceId": "68ca94e4484ef74ddeef2ba689393e8c"
계약 완료되어있고
개발 연동 체험 상점이 아닌 상점ID 테스트키로 해봤습니다
"traceId": "68ca94e4484ef74ddeef2ba689393e8c"
계약 완료되어있고
개발 연동 체험 상점이 아닌 상점ID 테스트키로 해봤습니다
암호화가 잘못된것으로 보입니다.
파이선이면 저희 가이드 에 있는

이코드 사용하시면 될텐데요.