Licensify 1.0.2
dotnet add package Licensify --version 1.0.2
NuGet\Install-Package Licensify -Version 1.0.2
<PackageReference Include="Licensify" Version="1.0.2" />
<PackageVersion Include="Licensify" Version="1.0.2" />
<PackageReference Include="Licensify" />
paket add Licensify --version 1.0.2
#r "nuget: Licensify, 1.0.2"
#:package Licensify@1.0.2
#addin nuget:?package=Licensify&version=1.0.2
#tool nuget:?package=Licensify&version=1.0.2
Licensify — C# / .NET SDK
Licensify 라이센스 인증을 가장 간단하게 붙이는 C# / .NET 라이브러리입니다.
복잡한 건 전부 SDK 안에 있습니다. 암호화 키 교환, 서버 신원 검증, 세션 유지(하트비트), 재시도까지
SDK가 알아서 처리하므로 여러분은 AuthenticateAsync 하나만 호출하면 됩니다. 라이센스 키만
넘기면 곧바로 인증된 세션을 받습니다. 연동은 몇 줄이면 충분합니다.
라이센스 발급, 소프트웨어 등록, 세션·사용 현황 관리는 모두 관리자 홈페이지 licensify.kr 에서 합니다. 이 SDK는 거기서 발급한 라이센스를 여러분의 앱에서 인증하는 클라이언트입니다.
요구 사항
- .NET 8.0 이상 (HKDF는 .NET 5+ 필요,
new AesGcm(key, 16)은 .NET 8의 태그 크기 지정 형식). - BouncyCastle.Cryptography 2.4.0 — X25519와 Ed25519는 .NET 기본 라이브러리(BCL)에 없습니다.
설치
dotnet add package Licensify
빠른 시작
using Licensify;
await using var client = new LicenseClient(
appId: "myapp", // 플랫폼 소프트웨어 ID (≤ 10자)
clientVersion: "1.2.0" // 앱 버전 (≤ 20자)
);
try
{
Session session = await client.AuthenticateAsync(userEnteredLicenseKey);
Console.WriteLine($"인증됨. 남은 시간 {session.RemainingMillis} ms.");
Console.WriteLine($"theme = {session.LocalVariables.GetValueOrDefault("theme")}");
// ... 앱 실행; 하트비트 루프가 세션을 자동으로 살아있게 유지합니다 ...
await session.SetLocalVariableAsync("highscore", "9001");
}
catch (LicenseException ex)
{
// 모든 실패는 이 한 타입으로 흐릅니다. ex.Code로 분기하세요.
switch (ex.Code)
{
case LicenseErrorCode.LicenseBanned:
Console.WriteLine($"정지됨: {ex.Reason} (해제 시각 {ex.Until})");
break;
case LicenseErrorCode.UpdateRequired:
Console.WriteLine($"{ex.LatestVersion}(으)로 업데이트하세요: {ex.DownloadUrl}");
break;
case LicenseErrorCode.NetworkError when ex.Retryable:
Console.WriteLine("네트워크 문제 — 다시 시도하세요.");
break;
default:
Console.WriteLine($"{ex.Code}: {ex.Message}");
break;
}
}
// DisposeAsync()가 빠져나갈 때 세션을 (best-effort로) 해제합니다.
옵션과 함께
모든 옵션은 선택 사항이며, 커스터마이즈 가능한("OPEN") 영역만 다룹니다. 보안과 관련된 모든 것은 SDK 내부에 잠겨 있습니다.
var client = new LicenseClient("myapp", "1.2.0", new LicenseClientOptions
{
FileHash = sha256OfMyBinary, // 선택적 무결성 검사 (≤ 64자)
AutoReauthenticate = true, // 세션 상실 시 1회 자동 재인증
OnSessionLost = err => LockTheApp(err), // 세션 도중 하트비트 실패 / 만료 / 정지
OnUpdateRequired = info => ShowUpdatePrompt(info.LatestVersion, info.DownloadUrl),
Logger = (level, msg) => Console.WriteLine($"[{level}] {msg}"), // 비밀값은 절대 로깅하지 않음
UserAgentSuffix = "MyApp", // 서버 로깅용으로 User-Agent에 덧붙임
});
공개 API
// 생성 — 서버 URL과 서명 키는 내부 상수이며 인자로 받지 않습니다.
new LicenseClient(string appId, string clientVersion, LicenseClientOptions? options = null);
Task<Session> AuthenticateAsync(string licenseKey, CancellationToken ct = default);
Task ReleaseAsync(CancellationToken ct = default); // best-effort, 멱등
bool IsActive { get; }
// Session — 사용에 필요한 부분만; 모든 암호 상태는 숨겨져 있습니다.
long Session.RemainingMillis; // 권위값, remainMs 기반
IReadOnlyDictionary<string,string> Session.LocalVariables;
IReadOnlyDictionary<string,string> Session.GlobalVariables;
string Session.LatestVersion;
string Session.Exp; // 표시 전용
string Session.ServerTime; // 표시 전용
Task Session.SetLocalVariableAsync(string key, string value, CancellationToken ct = default);
클라이언트는 IAsyncDisposable/IDisposable입니다. await using을 쓰면 스코프가 끝날 때 세션이
해제됩니다. 전역 종료 훅은 등록하지 않으므로, 앱 종료 시 직접 ReleaseAsync()(또는 dispose)를
호출하세요. 해제하지 못한 채 프로세스가 죽어도 서버의 60초 세션 TTL이 정리합니다.
에러 코드
모든 실패는 LicenseException으로 흐릅니다. Code(LicenseErrorCode)로 분기하고,
Retryable·Context와 편의 접근자(Reason, Until, LatestVersion, DownloadUrl)를
사용하세요. ServerCode에는 원본 서버 코드(예: "SDK_102")가 로깅용으로 담깁니다. 전체 목록과
서버 코드 매핑은 LicenseErrorCode를 참고하세요.
보안 (요약)
- 서버는 자기만 아는 키로 응답에 서명하고, SDK가 내장된 공개키로 검증 → 가짜 서버·중간자(MITM) 차단
- 매 세션 일회용 키로 AES-256-GCM 암호화 + 시퀀스 기반 재전송 방지
⚠️ 앱 자체 보호는 개발자 몫입니다
SDK는 통신을 안전하게 만들지만 여러분의 빌드된 앱을 보호하진 못합니다. 공격자가 여러분 바이너리에서
AuthenticateAsync 호출이나 그 결과를 검사하는 분기(if)·해시 검사 자체를 뜯어내면 SDK가 막을 길이
없습니다 — 그건 SDK가 아니라 여러분의 코드이기 때문입니다. 그래서:
- 배포 바이너리는 반드시 난독화하세요
- 인증·무결성 검사를 한 곳에 몰지 말고 여러 군데에 흩어 넣으세요
- 검사 결과를 우회하기 어렵게 설계하세요
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- BouncyCastle.Cryptography (>= 2.4.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.2 | 91 | 8/9/2026 |
서버 프로토콜 v2.4 대응: init 응답의 keyId로 검증 공개키를 선택하도록 변경(6필드 서명). 구버전은 최신 서버에서 init 검증에 실패하므로 업데이트가 필요합니다.