개요
PlayReady 테스트 서버에는 클라이언트에서 생성한 라이선스 요청 챌린지에서 라이선스 서버에서 사용할 수 있는 정보를 반영하는 특수 clientinfo 기능이 포함되어 있습니다. 이 기능을 사용하면 개발자가 라이선스 서버로 전송되는 클라이언트 정보를 쉽게 검사하고 클라이언트 기능에 따라 적절한 라이선스 생성 논리를 빌드할 수 있습니다. 예상 동작은 PlayReady 테스트 서버가 오류 응답 필드에 데이터가 CustomData 있는 서버별 오류(0x8004c604)임을 나타내는 오류 문자열로 clientinfo 회신하는 것입니다.
클라이언트 정보 기능
매개 변수를 clientinfo 사용하여 라이선스 요청에서 전송된 클라이언트 정보를 검사합니다.
테스트 서버 URL:
http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(msg:clientinfo)
SOAP 작업:
http://schemas.microsoft.com/DRM/2007/03/protocols/AcquireLicense
샘플 요청 구조
클라이언트 정보 기능은 표준 PlayReady 라이선스 취득 요청을 처리하고 라이선스 대신 클라이언트에 대한 자세한 정보를 반환합니다. 일반적인 요청의 구조는 다음과 같습니다.
<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<AcquireLicense xmlns="http://schemas.microsoft.com/DRM/2007/03/protocols">
<challenge>
<Challenge xmlns="http://schemas.microsoft.com/DRM/2007/03/protocols/messages">
<LA xmlns="http://schemas.microsoft.com/DRM/2007/03/protocols"
Id="SignedData" xml:space="preserve">
<Version>1</Version>
<ContentHeader>
<WRMHEADER xmlns="http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader"
version="4.0.0.0">
<DATA>
<PROTECTINFO>
<KEYLEN>16</KEYLEN>
<ALGID>AESCTR</ALGID>
</PROTECTINFO>
<KID>JpbjtvscoUq8vU7xq6eEOg==</KID>
<LA_URL>https://test.playready.microsoft.com/service/rightsmanager.asmx</LA_URL>
<LUI_URL>https://test.playready.microsoft.com/service/getrights.html</LUI_URL>
</DATA>
</WRMHEADER>
</ContentHeader>
<CLIENTINFO>
<CLIENTVERSION>10.0.16384.10011</CLIENTVERSION>
</CLIENTINFO>
<RevocationLists>
<RevListInfo>
<ListID>ioydTlK2p0WXkWklprR5Hw==</ListID>
<Version>11</Version>
</RevListInfo>
<!-- Additional revocation lists... -->
</RevocationLists>
<LicenseNonce>YCBas7tAUmkjOcabdD4DuQ==</LicenseNonce>
<ClientTime>1488568844</ClientTime>
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#"
Type="http://www.w3.org/2001/04/xmlenc#Element">
<!-- Encrypted client data... -->
</EncryptedData>
</LA>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<!-- Digital signature... -->
</Signature>
</Challenge>
</challenge>
</AcquireLicense>
</soap:Body>
</soap:Envelope>
샘플 응답: Windows 10 Edge 브라우저
Windows 10에서 Microsoft Edge에서 발급한 챌린지의 경우:
Client Info:
Client Version: 10.0.16384.10011
Client Time: 10/01/2017 2:00:00 PM
Supported Features:
Receiver
AntiRollbackClock
RevocationLists
PlayReady3Features
Device Certificate Info (Cert 0):
Platform: WindowsOnX86
Type: Device
SecurityLevel: 2000
RobustnessVersion: 100925543
DigestValue: 04+2aK5sjv+m5/EUY9BIMFqe0ResBkL9wfuFepWDU9E=
IssuerKey: h/k8EU71zsgAqa0niR1TnpKDC6dyOEgUGjybc3+s/EnUJWpkMtOwygoyCPp1nuRCFDvfoaaI78kb2fqGBI0tWg==
Binding Key Type: 3
Certificate Chain:
↳ Cert 1:
ManufacturerName: Microsoft
ModelName: Windows
ModelNumber: 6.4.0.103
DigestValue: LLp1fynIs9tgDxDDU+8jFveBoQp+0x8fXnqyV9tk1Zc=
Platform: WindowsOnX86
↳ Cert 2:
ManufacturerName: Microsoft
ModelName: PlayReady SL2000 Device Port- Windows Lib Codebase Version CA
ModelNumber: 1.0.0.4
DigestValue: Y3C0kjOxz3h/njYBKeApsvfPscwLcV1qAiTfAXXSLw4=
↳ Cert 3:
ManufacturerName: Microsoft
ModelName: PlayReady SL2000 Device Port - Windows Platform CA for x86/amd64
ModelNumber: 1.0.0.3
DigestValue: L62pDo9+gkd6LoLDbQwgxwtYldcuhSEog7GcJwtJ3CE=
↳ Cert 4:
ManufacturerName: Microsoft
ModelName: PlayReady SL2000 Device Port + Link CA
ModelNumber: 1.0.0.1
DigestValue: 7Q8z1rSr8I3AGkcf0BNoDgwS46nO0wD5m0WvYfFoTWQ=
샘플 응답: PlayReady 3.2 SL3000 클라이언트
PlayReady 3.2 기반 SL3000 클라이언트에서 발급한 챌린지의 경우:
Client Info:
Client Version: 3.2.0.4242
Client Time: 10/01/2017 2:00:00 PM
Supported Features:
SecureClock
RevocationLists
Receiver
Transmitter
PlayReady3Features
Device Certificate Info (Cert 0):
Platform: OEM
Type: Device
SecurityLevel: 3000
RobustnessVersion: 0
ManufacturerName: Contoso
ModelName: Cool Device Name
ModelNumber: Cool Device Name
DigestValue: IOSxDmGiRlX+dUf62sohHj/IB0qRKSkV7wz7sbZ3HSo=
IssuerKey: UlT6XXcgAMzaVAJN9JLJVomCFwppjoqgMMcT748yX27D053iiEP69pjEBnTxWiSEVXj76/e2wDImTgQDtbLTVg==
Binding Key Type: 3
Certificate Chain:
↳ Cert 1:
ManufacturerName: Contoso
ModelName: Cool Device Name
ModelNumber: ABC-XYZ-123
DigestValue: rmnxSlpuh9WTlXa6ACLcSJDnPVtoS5/2P1wa/kEgs1M=
↳ Cert 2:
ManufacturerName: Contoso
DigestValue: 5H3YVzR9EhHVnsseOJmO/ZCrX10Z8bOx9PDhKOhrxe4=
↳ Cert 3:
ManufacturerName: Microsoft
ModelName: PlayReady SL3000 Device Port + Link CA
ModelNumber: 1.0.0.1
DigestValue: bk7YOJRioSgnzjpZgLasowaL96LFIBHDx6B0z+JoDPE=
클라이언트 정보 요소
기본 클라이언트 정보
| 분야 | 설명 | 예제 값 |
|---|---|---|
| 클라이언트 버전 | PlayReady 클라이언트 버전 |
10.0.16384.10011, 3.2.0.4242 |
| 클라이언트 시간 | 클라이언트 시스템 시간 | 10/01/2017 2:00:00 PM |
| 플랫폼 | 클라이언트 플랫폼 식별자 |
WindowsOnX86, OEM |
지원되는 기능
| 특징 | 설명 |
|---|---|
| 수신기 | 클라이언트는 콘텐츠를 수신하고 암호를 해독할 수 있습니다. |
| 송신기 | 클라이언트는 다른 디바이스로 콘텐츠를 전송할 수 있습니다. |
| AntiRollbackClock | 클라이언트에서 롤백 방지 클록 기능을 지원합니다. |
| RevocationLists | 클라이언트에서 해지 목록 처리를 지원합니다. |
| PlayReady3Features | 클라이언트가 PlayReady 3.0 이상 기능을 지원합니다. |
| SecureClock | 클라이언트에서 보안 클록 기능을 지원합니다. |
보안 수준 정보
| 보안 수준 | 설명 | 사용 사례 |
|---|---|---|
| SL150 | 소프트웨어 기반 보호 | 기본 콘텐츠 보호 |
| SL2000 | 하드웨어 기반 보호 | 표준 프리미엄 콘텐츠 |
| SL3000 | 하드웨어 보안 모듈 | 울트라 프리미엄 콘텐츠 |
인증서 체인 정보
체인의 각 인증서는 다음을 제공합니다.
- ManufacturerName - 디바이스 제조업체
- ModelName - 디바이스 모델 식별자
- ModelNumber - 특정 모델 버전
- DigestValue - 인증서 지문
- 플랫폼 - 하드웨어 플랫폼 유형
테스트 시나리오
클라이언트 기능 검색
async function detectClientCapabilities() {
const clientInfoUrl = 'http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(msg:clientinfo)';
try {
const response = await sendLicenseRequest(clientInfoUrl);
const clientInfo = parseClientInfoResponse(response);
return {
version: clientInfo.clientVersion,
securityLevel: clientInfo.deviceCert.securityLevel,
features: clientInfo.supportedFeatures,
platform: clientInfo.deviceCert.platform,
manufacturer: clientInfo.certificateChain[0].manufacturerName
};
} catch (error) {
console.error('Failed to detect client capabilities:', error);
return null;
}
}
보안 수준 유효성 검사
async function validateSecurityLevel(requiredLevel) {
const clientInfo = await detectClientCapabilities();
if (!clientInfo) {
return { valid: false, reason: 'Could not detect client capabilities' };
}
const clientLevel = parseInt(clientInfo.securityLevel);
const required = parseInt(requiredLevel);
return {
valid: clientLevel >= required,
clientLevel: clientLevel,
requiredLevel: required,
reason: clientLevel >= required ? 'Security level sufficient' : 'Security level insufficient'
};
}
기능 호환성 테스트
async function testFeatureCompatibility(requiredFeatures) {
const clientInfo = await detectClientCapabilities();
if (!clientInfo) {
return { compatible: false, reason: 'Could not detect client features' };
}
const missingFeatures = requiredFeatures.filter(
feature => !clientInfo.features.includes(feature)
);
return {
compatible: missingFeatures.length === 0,
supportedFeatures: clientInfo.features,
missingFeatures: missingFeatures,
requiredFeatures: requiredFeatures
};
}
라이선스 서버 구현
라이선스 결정에 클라이언트 정보 사용
public class ClientInfoBasedLicenseHandler
{
public LicenseResponse GenerateLicense(LicenseRequest request)
{
var clientInfo = ExtractClientInfo(request.Challenge);
// Determine security level
var securityLevel = GetSecurityLevel(clientInfo);
// Check feature support
var supportedFeatures = GetSupportedFeatures(clientInfo);
// Build license based on client capabilities
var license = new LicenseBuilder()
.WithSecurityLevel(securityLevel)
.WithFeatures(supportedFeatures)
.WithOutputProtections(GetOutputProtections(securityLevel))
.Build();
return new LicenseResponse(license);
}
private SecurityLevel GetSecurityLevel(ClientInfo clientInfo)
{
switch (clientInfo.DeviceCertificate.SecurityLevel)
{
case 3000:
return SecurityLevel.SL3000;
case 2000:
return SecurityLevel.SL2000;
default:
return SecurityLevel.SL150;
}
}
private List<string> GetSupportedFeatures(ClientInfo clientInfo)
{
var features = new List<string>();
if (clientInfo.SupportedFeatures.Contains("PlayReady3Features"))
{
features.Add("AdvancedOutputProtection");
features.Add("SecureStop");
}
if (clientInfo.SupportedFeatures.Contains("SecureClock"))
{
features.Add("AntiRollback");
}
return features;
}
}
Platform-Specific 라이선스 논리
public OutputProtectionLevels DetermineOutputProtections(ClientInfo clientInfo)
{
var protections = new OutputProtectionLevels();
// Adjust based on platform
switch (clientInfo.Platform.ToLower())
{
case "windowsonx86":
case "windowsonx64":
protections.CompressedDigitalVideo = 270;
protections.UncompressedDigitalVideo = 270;
break;
case "oem":
// Custom OEM device - check manufacturer
if (IsHighSecurityOEM(clientInfo.ManufacturerName))
{
protections.CompressedDigitalVideo = 270;
protections.UncompressedDigitalVideo = 270;
}
else
{
protections.CompressedDigitalVideo = 200;
protections.UncompressedDigitalVideo = 200;
}
break;
default:
// Conservative defaults for unknown platforms
protections.CompressedDigitalVideo = 150;
protections.UncompressedDigitalVideo = 150;
break;
}
return protections;
}
클라이언트 정보 분석
Windows 플랫폼 분석
Windows 10 Edge 클라이언트 특성:
- 플랫폼:
WindowsOnX86 - 보안 수준:
2000(SL2000) - 견고성 버전: 하드웨어별 값
- 인증서 체인: Microsoft에서 발급한 인증서
- 기능: 표준 PlayReady 3.0 기능 집합
OEM 디바이스 분석
사용자 지정 OEM 클라이언트 특성:
- 플랫폼:
OEM - 보안 수준:
3000(SL3000) - 제조업체: 사용자 지정 OEM 이름
- 인증서 체인: OEM + Microsoft 인증서
- 기능: 고급 PlayReady 3.0 이상 기능
모범 사례
클라이언트 정보 사용
- 보안 수준 유효성 검사 - 클라이언트가 콘텐츠 보안 요구 사항을 충족하는지 확인
- 기능 검색 - 지원되는 기능에 따라 라이선스 조정
- 플랫폼 최적화 - 특정 플랫폼에 대한 설정 최적화
- 인증서 유효성 검사 - 인증서 체인 무결성 확인
- 기능 일치 - 콘텐츠 요구 사항을 클라이언트 기능과 일치
라이선스 생성 전략
- 보수적 기본값 - 알 수 없는 클라이언트에 안전한 기본값 사용
- 점진적 향상 - 클라이언트 기능을 기반으로 기능 추가
- 보안 우선 - 기능보다 보안 우선 순위 지정
- 플랫폼 인식 - 플랫폼별 제한 사항 고려
- 향후 호환성 - 앞으로 호환성을 위한 디자인
관련 설명서
- PlayReady 테스트 서버 서비스 - 주 테스트 서버 기능
- 쿼리 문자열 구문 - 매개 변수 구문 참조
- 출력 보호 테스트 - 출력 보호 테스트
- PlayReady 테스트 서버 - 전체 서버 설명서