Exemple #1
0
        public string ComputeChecksumAsync(IComputeChecksumCallback callback)
        {
            if (isDir_)
            {
                checksum_ = "";
            }
            else
            {
                FileStream fstr = null;
                try
                {
                    fstr = new FileStream(name_, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    MD5CryptoServiceProvider md5er = new MD5CryptoServiceProvider();
                    int    bufsize = 64 * 1024;                  //64K Buffer
                    byte[] buf     = new byte[bufsize];
                    long   curpos  = 0;
                    while (true)
                    {
                        int readCount = fstr.Read(buf, 0, bufsize);
                        if (readCount < bufsize)
                        {
                            md5er.TransformFinalBlock(buf, 0, readCount);
                            curpos = size_;
                            break;
                        }
                        else
                        {
                            md5er.TransformBlock(buf, 0, readCount, buf, 0);
                            curpos += readCount;
                        }
                        if (callback != null)
                        {
                            if (!callback.RaiseCallback(curpos, size_))
                            {
                                throw new Exception("Checksum computation will be aborted by user.");
                            }
                        }
                    }

                    StringBuilder md5str = new StringBuilder();
                    foreach (byte b in md5er.Hash)
                    {
                        md5str.AppendFormat("{0:X2}", b);
                    }
                    checksum_ = md5str.ToString();
                }
                catch (Exception ex)
                {
                    return(ex.Message);
                }
                finally
                {
                    if (fstr != null)
                    {
                        fstr.Close();
                    }
                }
            }

            return(null);
        }
    private string ComputeValidator( string strURL, string strUserAgent )
    {
        string strRandom = String.Format( "{0:X8}", new Random().Next() );
        byte [] abRandom = Encoding.ASCII.GetBytes( strRandom );

        byte [] abStatic =
            Convert.FromBase64String( "ROkjAaKid4EUF5kGtTNn3Q==" );

        int p = 0;
        for( int i = 0; i < 3 && p != -1; i++ )
            p = strURL.IndexOf( '/', p + 1 );

        byte [] abURL = Encoding.ASCII.GetBytes( strURL.Substring( p ) );
        byte [] abUA = Encoding.ASCII.GetBytes( strUserAgent );

        MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
        MD5.TransformBlock( abURL, 0, abURL.Length, abURL, 0 );
        MD5.TransformBlock( abUA, 0, abUA.Length, abUA, 0 );
        MD5.TransformBlock( abStatic, 0, abStatic.Length, abStatic, 0 );
        MD5.TransformFinalBlock( abRandom, 0, abRandom.Length );

        return String.Format( "{0}-{1}", strRandom,
            BitConverter.ToString( MD5.Hash ).Replace( "-", "" ) );
    }
Exemple #3
0
    /// <summary>
    /// The main processor -- convert a decrypted atom tree to an encrypted one.  See in-line comments.
    /// </summary>
    /// <returns>true if the operation was successful</returns>
    public bool Process()
    {
        // Get the position of mdat before changes -- this will be necessary for chunk table offseting
        long positionBefore = _root.Child("mdat").Position;

        // Find the mp4a atom -- if not found, we're given a wrong file
        Atoms mp4a = _root.Child("moov").Child("trak").Child("mdia").Child("minf").Child("stbl").Child("stsd").Child("mp4a");

        if (mp4a == null || _outfile == null)
        {
            return(false);
        }
        Atoms sinf = mp4a.AppendAtom("sinf", null);

        // Append an atom to sinf, containing the data "mp4a"
        byte[] frma = Encoding.ASCII.GetBytes("mp4a");
        sinf.AppendAtom("frma", frma);

        // Append an atom to sinf, containing the data "itun" and 8 NULLs.  Then append the schi atom to sinf
        byte[] schm = new byte[12];
        schm.Initialize();
        Encoding.ASCII.GetBytes("itun", 0, 4, schm, 4);

        sinf.AppendAtom("schm", schm);
        Atoms schi = sinf.AppendAtom("schi", null);

        // Grab the private key from the configuration file
        byte[] privateKey = Utility.ToByteArray(ConfigurationSettings.AppSettings["privateKey"]);

        // Append the user atom to schi
        schi.AppendAtom("user", Utility.ToByteArray(ConfigurationSettings.AppSettings["user"]));

        // Grab the key from the configuration file (obtained using iTunes' server) and append to schi
        byte[] keyData = BitConverter.GetBytes(Convert.ToInt32(ConfigurationSettings.AppSettings["key"]));
        Utility.Reverse(keyData);
        schi.AppendAtom("key ", keyData);

        // Grab the iviv and append to schi
        byte[] ivivData = Utility.ToByteArray(ConfigurationSettings.AppSettings["iviv"]);
        schi.AppendAtom("iviv", ivivData);

        // Grab the righ and append to schi
        byte[] righData = Utility.ToByteArray(ConfigurationSettings.AppSettings["righ"], 80);
        schi.AppendAtom("righ", righData);

        // Append the name atom (with the user's name, followed by NULLs) to schi
        byte[] nameData = new byte[256];
        Encoding.ASCII.GetBytes(ConfigurationSettings.AppSettings["name"]).CopyTo(nameData, 0);
        string nameString = Encoding.ASCII.GetString(nameData);

        schi.AppendAtom("name", nameData);

        // Append the priv data to schi, and encrypt it
        byte[] privData = Utility.ToByteArray(ConfigurationSettings.AppSettings["priv"], 440);
        schi.AppendAtom("priv", privData);
        byte[] privDataEncrypted = new byte[440];
        privData.CopyTo(privDataEncrypted, 0);

        // Hash the name and the iviv
        MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();

        byte[] nameHashed = new byte[16];
        MD5.TransformBlock(nameData, 0, nameString.IndexOf('\0'), nameHashed, 0);
        MD5.TransformFinalBlock(ivivData, 0, ivivData.Length);

        // Perform the encryption of the hash to get the new key and iv
        Utility.RijndaelCrypt(privData, 0, privData.Length, privateKey, MD5.Hash, false);
        if (Encoding.ASCII.GetString(privData, 0, 4) != "itun")
        {
            throw new Exception("The priv atom, the privateKey, or the name and iviv fields are invalid");
        }
        byte[] mdatKey = new byte[16];
        Array.Copy(privData, 24, mdatKey, 0, 16);
        byte[] mdatIV = new byte[16];
        Array.Copy(privData, 48, mdatIV, 0, 16);

        // Get the sample table
        Atoms stbl = _root.Child("moov").Child("trak").Child("mdia").Child("minf").Child("stbl");
        Atoms stsz = stbl.Child("stsz");

        GetSampleTable(stsz.Data);
        byte[] mdatData = _root.Child("mdat").Data;
        int    offset   = 0;

        // Encrypt all the chunks using the new key and iviv
        for (int i = 0; i < _table.Length; ++i)
        {
            Utility.RijndaelCrypt(mdatData, offset, (int)_table[i], mdatKey, mdatIV, true);
            offset += (int)_table[i];
        }

        // Change the type from m4pa to drms.  Update chunk sizes (since we've appended quite a lot!)
        mp4a.Type = "drms";
        _root.GetAndUpdateSize();

        // Update the chunk table (since the offsets shifted)
        long  positionAfter = _root.Child("mdat").Position;
        Atoms stco          = stbl.Child("stco");

        UpdateChunkTable(stco.Data, (int)(positionAfter - positionBefore));

        // Write the resulting data to the output file
        byte[] data = _root.Bytes;
        _output.Write(data, 0, data.Length);
        return(true);
    }