예제 #1
0
        /// <summary>
        /// Generates a PlayReady Header for the provided key ID.
        /// </summary>
        public static byte[] GenerateRightsManagementHeader(this HelpersContainerClasses.PlayReady container, Guid keyId)
        {
            var kidString = Convert.ToBase64String(keyId.ToByteArray());

            // Plain text manipulation here to keep things simple. Some common issues include:
            // 1) The first element must be EXACTLY as written here. Including small things like order of attributes.
            // 2) There must be no extra whitespace anywhere.
            var xml = $"<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>{kidString}</KID></DATA></WRMHEADER>";

            var xmlBytes = Encoding.Unicode.GetBytes(xml);

            using (var buffer = new MemoryStream())
            {
                using (var writer = new BinaryWriter(buffer))
                {
                    // Size (32)
                    // RecordCount (16)
                    //		RecordType (16)
                    //		RecordLength (16)
                    //		Data (xml)

                    writer.Write(xmlBytes.Length + 4 + 2 + 2 + 2); // Length.
                    writer.Write((ushort)1);                       // Record count.
                    writer.Write((ushort)1);                       // Record type (RM header).
                    writer.Write((ushort)xmlBytes.Length);         // Record length.
                    writer.Write(xmlBytes);
                }

                return(buffer.ToArray());
            }
        }
예제 #2
0
        public static Guid GetKeyIdFromRightsManagementHeader(this HelpersContainerClasses.PlayReady container, string rmHeader)
        {
            Helpers.Argument.ValidateIsNotNullOrWhitespace(rmHeader, nameof(rmHeader));

            var document = XDocument.Parse(rmHeader);

            var kidElement = document.Root
                             .Element(XName.Get("DATA", PlayReadyConstants.RightsManagementHeaderNamespace))
                             ?.Element(XName.Get("KID", PlayReadyConstants.RightsManagementHeaderNamespace));

            if (kidElement == null)
            {
                throw new ArgumentException("Rights Management header does not contain the KID element.", nameof(rmHeader));
            }

            var kidString = kidElement.Value;

            return(new Guid(Convert.FromBase64String(kidString)));
        }
예제 #3
0
        public static Guid GetKeyIdFromPlayReadyHeader(this HelpersContainerClasses.PlayReady container, byte[] playReadyHeader)
        {
            Helpers.Argument.ValidateIsNotNullOrEmpty(playReadyHeader, nameof(playReadyHeader));

            using (var reader = new BinaryReader(new MemoryStream(playReadyHeader)))
            {
                var headerLength = reader.ReadUInt32();

                if (headerLength != playReadyHeader.Length)
                {
                    throw new ArgumentException("PlayReady header does not have the expected size.");
                }

                var recordCount = reader.ReadUInt16();

                for (int recordIndex = 0; recordIndex < recordCount; recordIndex++)
                {
                    var recordType   = reader.ReadUInt16();
                    var recordLength = reader.ReadUInt16();

                    // 1 is the Rights Management header.
                    if (recordType != 1)
                    {
                        reader.BaseStream.Position += recordLength;
                        continue;
                    }

                    var rmHeaderBytes = reader.ReadBytesAndVerify(recordLength);
                    var rmHeader      = Encoding.Unicode.GetString(rmHeaderBytes);

                    return(Helpers.PlayReady.GetKeyIdFromRightsManagementHeader(rmHeader));
                }
            }

            throw new ArgumentException("PlayReady header does not contain a rights management header.");
        }