콘텐츠로 이동

C# SDK

Signox.Sdk — C#(.NET·Unity)용 공식 SDK입니다. netstandard2.0 단일 타겟이라 .NET Framework 4.6.1+, .NET 5/6/7/8+, Unity 2019+ (IL2CPP 포함) 에서 그대로 동작합니다.

  • 모든 서버 응답을 제품 Ed25519 공개키로 서명검증한 뒤에만 신뢰합니다(위변조·재생 방어).
  • 기기 식별자(hwid)는 SDK가 내부에서 자동 생성합니다 — 호출자가 다룰 필요가 없습니다.
  • 판정은 예외가 아니라 LicenseResult 값으로 전달됩니다. 예외는 잘못된 인자(빈 키 등)에만 발생합니다.
  • 런타임 의존성은 BouncyCastle.Cryptography 하나뿐입니다(Ed25519 검증용, MIT).
Terminal window
dotnet add package Signox.Sdk

또는 .csproj:

<PackageReference Include="Signox.Sdk" Version="0.1.0" />
  1. DLL 직접 넣기 (권장, 가장 단순)Signox.Sdk.dllBouncyCastle.Cryptography.dllAssets/Plugins/에 복사합니다. 순수 관리코드라 IL2CPP 백엔드에서도 별도 설정이 필요 없습니다. BouncyCastle.Cryptography.dll은 NuGet 캐시 또는 nuget.org에서 받습니다.
  2. NuGetForUnityNuGetForUnitySignox.Sdk를 설치하면 의존성까지 자동으로 들어옵니다.

Unity에서 hwid 수집은 외부 프로세스 실행 또는 시스템 파일 읽기를 시도하며, 접근이 막힌 환경에서는 안전하게 저신뢰 폴백(weak_hwid)으로 떨어집니다.

using Signox.Sdk;
var client = new SignoxClient(new SignoxOptions
{
// 제품 공개키(SPKI PEM)는 반드시 앱에 임베드합니다. 아래 "공개키 임베드" 참고.
ProductPublicKey = @"-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEA... (제품별 공개키)
-----END PUBLIC KEY-----",
// BaseUrl 기본값: https://api.signox.kr
// CacheDir 지정 시 오프라인 폴백용 캐시를 디스크에 저장
CacheDir = System.IO.Path.Combine(
System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData),
"MyApp", "signox-cache"),
});
// 1) 활성화 (기기 등록) — 최초 1회, 멱등
LicenseResult act = client.Activate("S4K2MB-7IWQ3F-...", new ActivateOptions
{
Name = "홍길동의 노트북", // 대시보드 표시용(선택)
});
if (!act.Valid)
{
// act.Code: DEVICE_LIMIT_REACHED / VM_NOT_ALLOWED / NOT_FOUND ...
return;
}
// 2) 검증 — 앱 실행마다. 캐시(cache.ttl)로 재검증 자연 생략
LicenseResult v = client.Validate("S4K2MB-7IWQ3F-...");
if (v.Valid)
{
bool proExport = v.Features.TryGetValue("pro_export", out var pe) && pe is bool b && b;
// v.Code == VALID | IN_GRACE_PERIOD
}
else if (v.Code == ValidationCode.NETWORK_ERROR)
{
// 네트워크 실패 + 유효 캐시 없음 — "무효"와 구분해 UX 처리
}
메서드 용도
Validate(licenseKey) 라이센스+디바이스 검증(캐시·오프라인 폴백 포함)
Activate(licenseKey[, opts]) 디바이스 활성화(hwid·anomalies 자동 첨부)
Deactivate(licenseKey) 디바이스 해제(슬롯 반환)
Heartbeat(licenseKey) 생존 신호 + 가벼운 재검증
ReportUsage(licenseKey, feature[, value]) 메터링 사용량 보고
RequestOfflineFile(licenseKey) .lic 파일 발급(내용은 File.Content)
ValidateOffline(licContent) .lic 완전 로컬 검증(네트워크 불필요)
GetHwid() 진단용 — 이 기기의 hwid
그룹 코드
유효 VALID, IN_GRACE_PERIOD
무효(상태) SUSPENDED, REVOKED, EXPIRED
무효(요청/디바이스) NOT_FOUND, PRODUCT_INACTIVE, HWID_REQUIRED, DEVICE_NOT_ACTIVATED, DEVICE_LIMIT_REACHED, VM_NOT_ALLOWED, FEATURE_NOT_FOUND, USAGE_LIMIT_REACHED
SDK 전용 SIGNATURE_INVALID, NONCE_MISMATCH, OFFLINE_FILE_INVALID, HWID_MISMATCH, NETWORK_ERROR

NETWORK_ERROR판정 불가(네트워크 실패 + 유효 캐시 없음)를 뜻하며, 라이센스가 무효라는 뜻이 아닙니다. 네트워크 실패 시 SignoxOptions.OfflineGraceDays(기본 7일 — 캐시 저장 시점 기준, 0 = 폴백 안 함) 이내의 캐시가 있으면 Stale=true로 폴백합니다. 코드별 권장 UX는 온라인 활성화 가이드를 참고하세요.

인터넷이 없는 기기는 포털·대시보드 또는 온라인 기기에서 .lic 파일을 발급받아 씁니다. 전체 플로우는 오프라인 활성화를 참고하세요.

// (온라인) .lic 발급 — 성공 시 result.File.Content 에 파일 원문
LicenseResult issued = client.RequestOfflineFile("S4K2MB-7IWQ3F-...");
if (issued.Code == ValidationCode.VALID && issued.File != null)
System.IO.File.WriteAllText("license.lic", issued.File.Content);
// (오프라인) 완전 로컬 검증 — 네트워크 불필요, hwid 는 SDK 가 로컬 대조
string lic = System.IO.File.ReadAllText("license.lic");
LicenseResult offline = client.ValidateOffline(lic);
// offline.Code: VALID | IN_GRACE_PERIOD | EXPIRED | HWID_MISMATCH | SIGNATURE_INVALID | OFFLINE_FILE_INVALID

SignoxClient는 불변 설정으로 구성되며 여러 스레드에서 동시에 호출해도 안전합니다. 인스턴스는 앱 수명 동안 하나만 만들어 재사용하세요(hwid·캐시가 메모이즈됩니다).

ProductPublicKey는 반드시 앱에 임베드하세요. SDK는 서버에서 공개키를 조회하지 않습니다 — 네트워크로 공개키를 받아오면 중간자가 위조 키를 주입할 수 있기 때문입니다. 공개키는 비밀이 아니지만 바꿔치기 방지가 핵심입니다. 비밀키는 절대 클라이언트에 넣지 마세요(서버에만 존재합니다).