مطالب
مقایسه مجوزهای سورس باز

احتمالا همیشه برای شما سؤال بوده است که مجوزهای گوناگون سورس باز با هم چه فرقی دارند، یا اینکه اگر روزی خواستم پروژه‌ی خود را به صورت سورس باز ارائه کنم، کدامیک از مجوزهای موجود مناسب‌تر است و همچنین وقت مطالعه مقالات طولانی یا کتاب‌هایی چند صد صفحه‌ای در این مورد را نداشته‌اید.
جدول زیر کار مقایسه این مجوزها (موارد رایج‌تر) را به صورت مختصر و مفید و بر اساس سؤالات رایج کاربران، انجام می‌دهد:

نام مجوز آیا به کار مشتق شده از پروژه اصلی، می‌توانم نامی دیگر بدهم؟ آیا باید حتما کار مشتق شده سورس باز باقی بماند؟ آیا می‌توانم برای کار مشتق شده مجوزی جدید انتخاب کنم؟ آیا می‌توانم کار مشتق شده را بفروشم و کسب درآمد کنم؟

Apache License 2.0
بله خیر بله بله

Common Development and Distribution License (CDDL)
بله خیر بله (به مجوزهای سازگار دیگری از همین دست) بله

GNU General Public License 2.0 (GPLv2)
بله، اما حتما باید لیست تغییرات انجام شده نسبت به پروژه اصلی را نیز
ارائه بدهید.
بله بله (به مجوزهای سازگار دیگری از همین دست یا توافق با نویسنده اصلی) بله

GNU Library General Public License (LGPL)
بله بله، اما امکان استفاده از کتابخانه‌های کامپایل شده یک پروژه سورس باز
تحت این مجوز در یک پروژه سورس بسته نیز وجود دارد.
بله (به مجوزهای سازگار دیگری از همین دست) بله

Microsoft Public License (Ms-PL)
بله، اما نمی‌توانید از علامت تجاری خود استفاده کنید. خیر خیر بله

Microsoft Reciprocal License (Ms-RL)
بله، اما نمی‌توانید از علامت تجاری خود استفاده کنید. بله خیر بله

Mozilla Public License 1.1 (MPL)
بله خیر خیر بله

BSD License
بله خیر بله بله

MIT License
بله خیر بله بله



همچنین لازم به ذکر است که
مجوزهای کار اصلی و کار مشتق شده هر دو باید ذکر شوند.
پسندیده است که از نویسندگان کار اصلی، نامبرده شده و قدردانی گردد.
هیچکدام از این مجوزها مسؤولیتی را در قبال کار انجام شده نمی‌پذیرند!

جهت مطالعه بیشتر:
http://khason.net/blog/open-source-licenses-comparison-table/
http://developer.kde.org/documentation/licensing/licenses_summary.html
http://en.wikipedia.org/wiki/Comparison_of_free_software_licences

نظرات مطالب
مقایسه مجوزهای سورس باز
سلام. ممنون از این مطلب. سوالم این بود که در مجوز GNU General Public License 2.0 (GPLv2)
نوشته شده که حتما باید کار مشتق شده سورس باز باقی بماند و دیگر اینکه می توان کار خود را تحت مجوز دیگر منتشر کنیم حالا اگر برای کار مشتق شده جدید مجوز ما از نوع Common Development and Distribution License (CDDL) انتخاب شود در مورد سورس باز بودن کار با هم متناقض نمی شوند؟
نظرات مطالب
مقایسه مجوزهای سورس باز
در مورد CPL :
- آیا به کار مشتق شده از پروژه اصلی، می‌توانم نامی دیگر بدهم؟
بله.
- آیا باید حتما کار مشتق شده سورس باز باقی بماند؟
بله. اگر کار جدیدی است و از کدهای پروژه اول تحت مجوز CPL استفاده کرده.
خیر. اگر همان کار اولیه است و فقط کامپایل شده (فقط باید ذکر کنید سورس اصلی را از کجا می‌شود تهیه کرد).
در هر دو حالت، حتما باید ذکر کنید که کار جدید از چه کاری مشتق شده (به عبارتی تشکر فراموش نشود!)

- آیا می‌توانم برای کار مشتق شده مجوزی جدید انتخاب کنم؟
خیر. مگر با دریافت مجوز از صاحب اصلی کار. (و زمانیکه این مورد خیر شد یعنی نمی‌تونید از اینکار در یک پروژه جدید مثلا GPL استفاده کنید، مگر با نویسنده اصلی توافق کنید)

- آیا می‌توانم کار مشتق شده را بفروشم و کسب درآمد کنم؟
بله. (این بله در تمام مجوزها با توجه به شرایط قبل باید تفسیر شود. یعنی اگر در این مورد اخیر گفته شده بله، یعنی بله اگر سورس خودت رو در اختیار بقیه هم قرار دادی، چون در این مورد خاص صراحتا این مورد خواسته شده، اما مثلا مجوز MIT چنین چیزی رو نمی‌خواد)

ماخذ: (+)
اشتراک‌ها
بررسی و مقایسه بین مجوزهای اپن‌سورس
  • Apache License 2.0
  • BSD 3-Clause “New” or “Revised” license
  • BSD 2-Clause “Simplified” or “FreeBSD” license
  • GNU General Public License (GPL) v3.0
  • GNU Library or “Lesser” General Public License (LGPL)
  • MIT license
  • Mozilla Public License 2.0
  • Common Development and Distribution License
  • Eclipse Public License
  • Creative Commons License 
بررسی و مقایسه بین مجوزهای اپن‌سورس
مطالب
نکته‌ای تکمیلی در مورد مجوز استفاده از iTextSharp

یکی از سؤ برداشت‌های متداول از کارهای سورس باز موجود این است:
«من مجازم از این کتابخانه‌ی سورس باز هرجایی و هر طوری که دوست دارم استفاده کنم.»

در کل این یک «توهم» بزرگ است. بسته به مجوز پروژه (^)، جمله‌ی فوق می‌تواند صحیح یا کاملا نادرست باشد.
برای نمونه من خیلی‌ها رو می‌بینم که می‌گن: «از MySQL استفاده کن که رایگانه». نه دوست عزیز؛ اشتباه می‌کنید! فقط برای کارهای سورس باز رایگان است. مجوز نگارش Community و رایگان آن در رده‌ی مجوز‌های GPL است (^). به این معنا که اگر روزی مطابق قوانین کپی رایت قرار شد رفتار شود، به سراغ کار سورس بسته شما که دارد از MySQL رایگان استفاده می‌کند، خواهند آمد. جهت اطلاع!
به همین جهت کسانی که کار تجاری سورس بسته انجام می‌دهند از طرف کتابخانه‌های دارای مجوز GPL حتی رد هم نمی‌شوند؛ چه برسد به اینکه بخواهند آزادانه از آن استفاده کنند.

در مورد مجوز کتابخانه‌ی iTextSharp پیشتر مطلبی را در این سایت خوانده‌اید:
مجوز این کتابخانه، GNU Affero General Public License است. به این معنا که شما موظفید، تغییری در قسمت تهیه کننده خواص فایل PDF تولیدی که به صورت خودکار به نام کتابخانه تنظیم می‌شود، ندهید. اگر می‌خواهید این قسمت را تغییر دهید باید هزینه کنید. همچنین با توجه به اینکه این مجوز، GPL است یعنی زمانیکه از آن استفاده کردید باید کار خود را به صورت سورس باز ارائه دهید (^).

و ... نکته تکمیلی مهم اینکه:
این کتابخانه تا نگارش 4.1.7 تحت مجوز MPL/LGPL ارائه شده و «بدون مشکل» در کارهای تجاری سورس بسته قابل استفاده است. از نگارش 5 به بعد، AGPL شده و برای کارهای تجاری سورس بسته «رایگان نیست» (^).
برای نمونه سورس نسخه 4.1.7 از این آدرس قابل دریافت است.
این سورس را از پروژه "FDFToolkit .NET" اینجا نقل کردم چون تهیه کننده این پروژه دقیقا به این مطلب اشاره کرده و کار خود را به نگارش 4.1.7 کتابخانه iTextSharp عمدا محدود کرده است.

مطالب
مجوز WTFPL

در بین مجوز‌های سورس باز، یکی از اون‌ها که اتفاقا مورد پذیرش FSF هم هست، عنوان جالبی داره که ترجمه‌اش به فارسی می‌شود: "برو هر غلطی که دلت می‌خواد باهاش بکن!" یا WTFPL = Do What The F.u.c.k You Want To Public License
نگارش یک این مجوز توسط Banlu Kemiyatorn نویسنده برنامه Window maker در سال 2000 ارائه شده و در سال 2007 توسط مدیر پروژه تیم Debian نگارش دوم آن ارائه گردیده است!
این مجوز به شما اجازه هر نوع تغییر یا هر روش توزیعی را در مورد برنامه‌ی مورد نظر می‌دهد.
ترجمه این مجوز هم به زبان فارسی به صورت زیر است:

"
مجوز برو هر غلطی که دلت می‌خواد بکن!
نگارش 2، دسامبر 2004

هر کسی مجاز است این مستند را کپی یا توزیع کند با این شرط که اگر تغییری در اصل آن داده شد، نامش را تغییر دهد.
شروط اصلی این مجوز به شرح ذیل اعلام می‌گردد:
0- فقط برو هر غلطی که دلت می‌خواد باهاش بکن

"

البته شاید این سؤال پیش بیاد که این موارد به چه دلیلی اضافه شده؟ احتمالا شاید شنیده باشید که عده‌ای GPL‌ رو یک نوع سرطان می‌دونند؛ از این لحاظ که اگر طرف اون رفتید باید کل برنامه خودتون رو سورس باز ارائه بدید. به همین جهت کسانی که کار تجاری انجام می‌دهند از طرف سورس‌های پروژه‌های مبتنی بر GPL رد هم نمی‌شوند. در مقابل آن مجوزهایی مانند BSD یا MIT ملاحظات GPL را ندارند (+). در کل GPL تا به امروز لینوکس را زنده نگه داشته است.

نظرات مطالب
هزینه استفاده از دات نت فریم ورک چقدر است؟
مجوز رو می‌تونید اینجا مطالعه کنید:
http://www.opensource.org/licenses/ms-pl.html
و زمانیکه در این سایت مطرح شده یعنی پذیرفته شده و معتبر است.
توضیحات بیشتر هم در این سؤال و جواب:
http://programmers.stackexchange.com/questions/85301/understanding-the-microsoft-public-license-ms-pl
نظرات مطالب
هزینه استفاده از دات نت فریم ورک چقدر است؟
مجوز رو می‌تونید اینجا مطالعه کنید:
http://www.opensource.org/licenses/ms-pl.html
و زمانیکه در این سایت مطرح شده یعنی پذیرفته شده و معتبر است.
توضیحات بیشتر هم در این سؤال و جواب:
http://programmers.stackexchange.com/questions/85301/understanding-the-microsoft-public-license-ms-pl
مطالب
تهیه XML امضاء شده جهت تولید مجوز استفاده از برنامه
اگر به فایل مجوز استفاده از برنامه‌‌ای مانند EF Profiler دقت کنید، یک فایل XML به ظاهر ساده بیشتر نیست:
<?xml version="1.0" encoding="utf-8"?>
<license id="17d46246-a6cb-4196-98a0-ff6fc08cb67f" expiration="2012-06-12T00:00:00.0000000" type="Trial" prof="EFProf">
  <name>MyName</name>
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue>b8N0bDE4gTakfdGKtzDflmmyyXI=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>IPELgc9BbkD8smXSe0sGqp5vS57CtZo9ME2ZfXSq/thVu...=</SignatureValue>
  </Signature>
</license>
در این فایل ساده متنی، نوع مجوز استفاده از برنامه، Trial ذکر شده است. شاید عنوان کنید که خوب ... نوع مجوز را به Standard تغییر می‌دهیم و فایل را ذخیره کرده و نهایتا استفاده می‌کنیم. اما ... نتیجه حاصل کار نخواهد کرد! حتی اگر یک نقطه به اطلاعات این فایل اضافه شود، دیگر قابل استفاده نخواهد بود. علت آن هم به قسمت Signature فایل XML فوق بر می‌گردد.
در ادامه به نحوه تولید و استفاده از یک چنین مجوزهای امضاء شده‌ای در برنامه‌های دات نتی خواهیم پرداخت.


تولید کلیدهای RSA

برای تهیه امضای دیجیتال یک فایل XML نیاز است از الگوریتم RSA استفاده شود.
برای تولید فایل XML امضاء شده، از کلید خصوصی استفاده خواهد شد. برای خواندن اطلاعات مجوز (فایل XML امضاء شده)، از کلیدهای عمومی که در برنامه قرار می‌گیرند کمک خواهیم گرفت (برای نمونه برنامه EF Prof این کلیدها را در قسمت Resourceهای خود قرار داده است).
استفاده کننده تنها زمانی می‌تواند مجوز معتبری را تولید کند که دسترسی به کلیدهای خصوصی تولید شده را داشته باشد.
        public static string CreateRSAKeyPair(int dwKeySize = 1024)
        {
            using (var provider = new RSACryptoServiceProvider(dwKeySize))
            {
                return provider.ToXmlString(includePrivateParameters: true);
            }
        }
امکان تولید کلیدهای اتفاقی مورد استفاده در الگوریتم RSA، در دات نت پیش بینی شده است. خروجی متد فوق یک فایل XML است که به همین نحو در صورت نیاز توسط متد provider.FromXmlString مورد استفاده قرار خواهد گرفت.


تهیه ساختار مجوز

در ادامه یک enum که بیانگر انواع مجوزهای برنامه ما است را مشاهده می‌کنید:
namespace SignedXmlSample
{
    public enum LicenseType
    {
        None,
        Trial,
        Standard,
        Personal
    }
}
به همراه کلاسی که اطلاعات مجوز تولیدی را دربر خواهد گرفت:
using System;
using System.Xml.Serialization;

namespace SignedXmlSample
{
    public class License
    {
        [XmlAttribute]
        public Guid Id { set; get; }
        
        public string Domain { set; get; }

        [XmlAttribute]
        public string IssuedTo { set; get; }

        [XmlAttribute]
        public DateTime Expiration { set; get; }

        [XmlAttribute]
        public LicenseType Type { set; get; }
    }
}
خواص این کلاس یا عناصر enum یاد شده کاملا دلخواه هستند و نقشی را در ادامه بحث نخواهند داشت؛ از این جهت که از مباحث XmlSerializer برای تبدیل وهله‌ای از شیء مجوز به معادل XML آن استفاده می‌شود. بنابراین المان‌های آن‌را مطابق نیاز خود می‌توانید تغییر دهید. همچنین ذکر ویژگی XmlAttribute نیز اختیاری است. در اینجا صرفا جهت شبیه سازی معادل مثالی که در ابتدای بحث مطرح شد، از آن استفاده شده است. این ویژگی راهنمایی است برای کلاس XmlSerializer تا خواص مزین شده با آن‌را به شکل یک Attribute در فایل نهایی ثبت کند.


تولید و خواندن مجوز دارای امضای دیجیتال

کدهای کامل کلاس تولید و خواندن یک مجوز دارای امضای دیجیتال را در اینجا مشاهده می‌کنید:
using System;
using System.IO;
using System.Security.Cryptography; // needs a ref. to `System.Security.dll` asm.
using System.Security.Cryptography.Xml;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace SignedXmlSample
{
    public static class LicenseGenerator
    {
        public static string CreateLicense(string licensePrivateKey, License licenseData)
        {
            using (var provider = new RSACryptoServiceProvider())
            {
                provider.FromXmlString(licensePrivateKey);
                var xmlDocument = createXmlDocument(licenseData);
                var xmlDigitalSignature = getXmlDigitalSignature(xmlDocument, provider);
                appendDigitalSignature(xmlDocument, xmlDigitalSignature);
                return xmlDocumentToString(xmlDocument);
            }
        }

        public static string CreateRSAKeyPair(int dwKeySize = 1024)
        {
            using (var provider = new RSACryptoServiceProvider(dwKeySize))
            {
                return provider.ToXmlString(includePrivateParameters: true);
            }
        }

        public static License ReadLicense(string licensePublicKey, string xmlFileContent)
        {
            var doc = new XmlDocument();
            doc.LoadXml(xmlFileContent);

            using (var provider = new RSACryptoServiceProvider())
            {
                provider.FromXmlString(licensePublicKey);

                var nsmgr = new XmlNamespaceManager(doc.NameTable);
                nsmgr.AddNamespace("sig", "http://www.w3.org/2000/09/xmldsig#");

                var xml = new SignedXml(doc);
                var signatureNode = (XmlElement)doc.SelectSingleNode("//sig:Signature", nsmgr);
                if (signatureNode == null)
                    throw new InvalidOperationException("This license file is not signed.");

                xml.LoadXml(signatureNode);
                if (!xml.CheckSignature(provider))
                    throw new InvalidOperationException("This license file is not valid.");

                var ourXml = xml.GetXml();
                if (ourXml.OwnerDocument == null || ourXml.OwnerDocument.DocumentElement == null)
                    throw new InvalidOperationException("This license file is coruppted.");

                using (var reader = new XmlNodeReader(ourXml.OwnerDocument.DocumentElement))
                {
                    var xmlSerializer = new XmlSerializer(typeof(License));
                    return (License)xmlSerializer.Deserialize(reader);
                }
            }
        }

        private static void appendDigitalSignature(XmlDocument xmlDocument, XmlNode xmlDigitalSignature)
        {
            xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(xmlDigitalSignature, true));
        }

        private static XmlDocument createXmlDocument(License licenseData)
        {
            var serializer = new XmlSerializer(licenseData.GetType());
            var sb = new StringBuilder();
            using (var writer = new StringWriter(sb))
            {
                var ns = new XmlSerializerNamespaces(); ns.Add("", "");
                serializer.Serialize(writer, licenseData, ns);
                var doc = new XmlDocument();
                doc.LoadXml(sb.ToString());
                return doc;
            }
        }

        private static XmlElement getXmlDigitalSignature(XmlDocument xmlDocument, AsymmetricAlgorithm key)
        {
            var xml = new SignedXml(xmlDocument) { SigningKey = key };
            var reference = new Reference { Uri = "" };
            reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
            xml.AddReference(reference);
            xml.ComputeSignature();
            return xml.GetXml();
        }

        private static string xmlDocumentToString(XmlDocument xmlDocument)
        {
            using (var ms = new MemoryStream())
            {
                var settings = new XmlWriterSettings { Indent = true, Encoding = Encoding.UTF8 };
                var xmlWriter = XmlWriter.Create(ms, settings);
                xmlDocument.Save(xmlWriter);
                ms.Position = 0;
                return new StreamReader(ms).ReadToEnd();
            }
        }
    }
}
توضیحات:
در حین کار با متد CreateLicense، پارامتر licensePrivateKey همان اطلاعاتی است که به کمک متد CreateRSAKeyPair قابل تولید است. توسط پارامتر licenseData، اطلاعات مجوز در حال تولید اخذ می‌شود. در این متد به کمک provider.FromXmlString، اطلاعات کلیدهای RSA دریافت خواهند شد. سپس توسط متد createXmlDocument، محتوای licenseData دریافتی به یک فایل XML نگاشت می‌گردد (بنابراین اهمیتی ندارد که حتما از ساختار کلاس مجوز یاد شده استفاده کنید). در ادامه متد getXmlDigitalSignature با در اختیار داشتن معادل XML شیء مجوز و کلیدهای لازم، امضای دیجیتال متناظری را تولید می‌کند. با استفاده از متد appendDigitalSignature، این امضاء را به فایل XML اولیه اضافه می‌کنیم. از این امضاء جهت بررسی اعتبار مجوز برنامه در متد ReadLicense استفاده خواهد شد.
برای خواندن یک فایل مجوز امضاء شده در برنامه خود می‌توان از متد ReadLicense استفاده کرد. توسط آرگومان licensePublicKey، اطلاعات کلید عمومی دریافت می‌شود. این کلید دربرنامه، ذخیره و توزیع می‌گردد. پارامتر xmlFileContent معادل محتوای فایل XML مجوزی است که قرار است مورد ارزیابی قرار گیرد.


مثالی در مورد نحوه استفاده از کلاس تولید مجوز

در ادامه نحوه استفاده از متدهای CreateLicense و  ReadLicense را ملاحظه می‌کنید؛ به همراه آشنایی با نمونه کلیدهایی که باید به همراه برنامه منتشر شوند:
using System;
using System.IO;

namespace SignedXmlSample
{
    class Program
    {
        static void Main(string[] args)
        {
            //Console.WriteLine(LicenseGenerator.CreateRSAKeyPair());
            writeLicense();            
            readLicense();

            Console.WriteLine("Press a key...");
            Console.ReadKey();
        }

        private static void readLicense()
        {
            var xml = File.ReadAllText("License.xml");
            const string publicKey = @"<RSAKeyValue>
                                    <Modulus>
                                        mBNKFIc/LkMfaXvLlB/+6EujPkx3vBOvLu8jdESDSQLisT8K96RaDMD1ORmdw2XNdMw/6ZBuJjLhoY13qCU9t7biuL3SIxr858oJ1RLM4PKhA/wVDcYnJXmAUuOyxP/vfvb798o6zAC1R2QWuzG+yJQR7bFmbKH0tXF/NOcSgbc=
                                    </Modulus>
                                    <Exponent>
                                        AQAB
                                    </Exponent>
                                 </RSAKeyValue>";

            var result = LicenseGenerator.ReadLicense(publicKey, xml);

            Console.WriteLine(result.Domain);
            Console.WriteLine(result.IssuedTo);
        }

        private static void writeLicense()
        {
            const string rsaData = @"<RSAKeyValue>
                    <Modulus>
                        mBNKFIc/LkMfaXvLlB/+6EujPkx3vBOvLu8jdESDSQLisT8K96RaDMD1ORmdw2XNdMw/6ZBuJjLhoY13qCU9t7biuL3SIxr858oJ1RLM4PKhA/wVDcYnJXmAUuOyxP/vfvb798o6zAC1R2QWuzG+yJQR7bFmbKH0tXF/NOcSgbc=
                    </Modulus>
                    <Exponent>
                        AQAB
                    </Exponent>
                    <P>
                        xwPKN77EcolMTD2O2Csv6k9Y4aen8UBVYjeQ4PtrNGz0Zx6I1MxLEFzRpiKC/Ney3xKg0Icwj0ebAQ04d5+HAQ==
                    </P>
                    <Q>
                        w568t0Xe6OBUfCyAuo7tTv4eLgczHntVLpjjcxdUksdVw7NJtlnOLApJVJ+U6/85Z7Ji+eVhuN91yn04pQkAtw==
                    </Q>
                    <DP>
                        svkEjRdA4WP5uoKNiHdmMshCvUQh8wKRBq/D2aAgq9fj/yxlj0FdrAxc+ZQFyk5MbPH6ry00jVWu3sY95s4PAQ==
                    </DP>
                    <DQ>
                        WcRsIUYk5oSbAGiDohiYeZlPTBvtr101V669IUFhhAGJL8cEWnOXksodoIGimzGBrD5GARrr3yRcL1GLPuCEvQ==
                    </DQ>
                    <InverseQ>
                        wIbuKBZSCioG6MHdT1jxlv6U1+Y3TX9sHED9PqGzWWpVGA+xFJmQUxoFf/SvHzwbBlXnG0DLqUvxEv+BkEid2w==
                    </InverseQ>
                    <D>                        Yk21yWdT1BfXqlw30NyN7qNWNuM/Uvh2eaRkCrhvFTckSucxs7st6qig2/RPIwwfr6yIc/bE/TRO3huQicTpC2W3aXsBI9822OOX4BdWCec2txXpSkbZW24moXu+OSHfAdYoOEN6ocR7tAGykIqENshRO7HvONJsOE5+1kF2GAE=
                    </D>
                  </RSAKeyValue>";

            string data = LicenseGenerator.CreateLicense(
                                                rsaData,
                                                new License
                                                {
                                                     Id = Guid.NewGuid(),
                                                     Domain = "dotnettips.info",
                                                     Expiration = DateTime.Now.AddYears(2),
                                                     IssuedTo = "VahidN",
                                                     Type = LicenseType.Standard
                                                });
            File.WriteAllText("License.xml", data);
        }
    }
}
ابتدا توسط متد CreateRSAKeyPair کلیدهای لازم را تهیه و ذخیره کنید. این کار یکبار باید صورت گیرد.
همانطور که مشاهده می‌کنید، اطلاعات کامل یک نمونه از آن، در متد writeLicense مورد نیاز است. اما در متد readLicense تنها به قسمت عمومی آن یعنی Modulus و Exponent نیاز خواهد بود (موارد قابل انتشار به همراه برنامه).

سؤال: امنیت این روش تا چه اندازه است؟
پاسخ: تا زمانیکه کاربر نهایی به کلیدهای خصوصی شما دسترسی پیدا نکند، امکان تولید معادل آن‌ها تقریبا در حد صفر است و به طول عمر او قد نخواهد داد!
اما ... مهاجم می‌تواند کلیدهای عمومی و خصوصی خودش را تولید کند. مجوز دلخواهی را بر این اساس تهیه کرده و سپس کلید عمومی جدید را در برنامه، بجای کلیدهای عمومی شما درج (patch) کند! بنابراین روش بررسی اینکه آیا برنامه جاری patch شده است یا خیر را فراموش نکنید. یا عموما مطابق معمول قسمتی از برنامه که در آن مقایسه‌ای بین اطلاعات دریافتی و اطلاعات مورد انتظار وجود دارد، وصله می‌شوند؛ این مورد عمومی است و منحصر به روش جاری نمی‌باشد.

دریافت نسخه جنریک این مثال:
SignedXmlSample.zip
مطالب
اجزاء معماری سیستم عامل اندروید (قسمت اول بررسی مجوزها و مفهوم Intent در اندروید) :: بخش هفتم
Intent چیست؟
معنای لغوی intent : هدف، قصد، نیت و امثالهم...
intent‌ها حامل انواع پیام‌هایی هستند که بواسطه آنها یک پیام خاص و یکتا، برای کنترل وظایف و یا انتقال داده‌ها یا درخواست جدیدی از سیستم به دیگری می‌فرستد و درخواست ما پذیرفته یا رد می‌شود.
intent‌ها به سه بخش مشخص شدۀ خاص تقسیم می‌شوند: فعالیت‌ها ( activity) ، خدمات یا سرویس‌ها (services) و broadcast receiver که به معنی اینست که اتفاقات را در سطح اندروید به صورت broadcast اعلام می‌کند و در سیستم پخش می‌شود؛ مانند زمانیکه سیستم عامل میخواهد بوت شود. در اینصورت این پیغام توسط یک مجوز خاص و با broadcast در سیستم عامل به کاربر اعلام می‌شود. broadcast receiver در اندروید و درون هسته گنجانده شده و فقط سیستم عامل قادر به اجرای آن است؛ تا در زمان یک اتفاق غیرمنتظره به برنامه یا کاربر اطلاع داده شود و تنها ما از طریق یک مجوز میتوانیم به آن دسترسی داشته باشیم.
اجازه دهید یک مثال ساده را انتخاب کنیم که در آن درخواست شما به مرورگر اندروید نیاز دارد تا بتواند محتویات یک URL را بارگیری و محتوایی را نمایش دهد. برخی از اجزای اصلی یک شئ شامل intent action و intent data خواهد بود. برای مثال ما می‌خواهیم که کاربر مرورگر خود را ببیند. به همین منظور ما از یک نوع intent استفاده می‌کنیم تا برای کار با برخی داده‌ها لازم باشد که از یک URL استفاده کند. به صورت زیر:
Intent.ACTION_VIEW
شئ intent به صورت زیر ساخته می‌شود:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(https://github.com);

برای فراخوانی باید کد زیر در برنامه درج شود:
startActivity(intent);

نکته: برای کنترل اینکه کدام برنامه‌ها می‌توانند intent خاصی را دریافت کنند باید یک مجوز (permission) را قبل از فراخوانی به آن ارسال کنیم.

بررسی مجوزها
پلتفرم اندروید سیستم دسترسی به اشیاء intent‌ها را از طریق استفاده از مجوزها کنترل می‌کند که بعضا بسیاری از توسعه دهندگان این مورد را به اشتباه درک می‌کنند و زمان فراخوانی، توجهی به اینکه مجوزها کجا باید ارسال شوند نخواهند داشت.
نگاهی می‌اندازیم به اینکه چگونه یک برنامه می‌تواند کاربرنهایی را با یک مجوز خاص درخواست کند؟ به چه صورت و از کجا؟ به چه میزان این درخواست معتبر است؟
یک مکانیزم اعتبارسنجی کنترل مجوز را در سیستم‌عامل اندروید بررسی و اداره خواهد کرد. هنگامیکه برنامه شما یک API را فراخوانی می‌کند، مکانیم اعتبارسنجی به سرعت وارد کار شده و بررسی خواهد کرد که آیا مجوزهای این درخواست معتبر هستند و اگر معتبر هستند تمامی مجوزهای لازم را دارند یا خیر؟ پس از یک پیش پردازش در کسری از ثانیه اگر درخواست و مجوزها کامل نباشد یک "SecurityException" ارسال خواهد شد.
فراخوانی‌های API در سه مرحله جداگانه انجام می‌شوند. اول، کتابخانه API بکار گرفته می‌شود. دوم، کتابخانه به صورت خصوصی برای خود یک رابط پروکسی که بخشی از همان کتابخانه API می‌باشد را ایجاد می‌کند و در آخر این رابط پروکسی به صورت خصوصی ارتباط و پردازش‌های مورد نظر برای پرس و جو را زمانیکه سرویس در حال اجرا می‌باشد، عملیاتی می‌کند تا فرآیند فراخوانی تکمیل گردد.
این فرآیند در تصویر زیر نمایش داده شده است:


استفاده از Self-Defined Permissions 

اندروید به توسعه دهندگان اجازه می‌دهد تا مجوزهای خود را ساخته و آنها را اجرا کنند. همانند مجوزهای سیستمی که پلتفرم آنها را بررسی می‌کند، شما باید خواص و برچسب‌های مورد نیاز را در فایل AndroidManifest.xml اعلام کنید. اگر برنامه‌ای می‌نویسید که یک نوعِ خاص از قابلیت دسترسی توسط توسعه دهندگان را فراهم می‌کند، شما می‌توانید برای حفاظت از توابع با مجوزهای سفارشی خود، مانع دسترسی‌های غیرمجاز شوید. به کدی که در فایل AndroidMainfest درج شده دقت نمایید:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.zenconsult.mobile.testapp" >
<permission android:name="net.zenconsult.mobile.testapp.permission.PURGE_DATABASE"
android:label="@string/label_purgeDatabase"
android:description="@string/description_purgeDatabase"
android:protectionLevel="dangerous" />
...
</manifest>
نام مجوز در کد فوق را باید در این قسمت تعیین کنید:
android:name <attribute>
خواص و ویژگی‌های مورد نیاز در این قسمت باید نوشته شوند (الزامیست)
android:label
android:description
تمامی موارد فوق به رشته‌هایی اشاره دارد که در فایل AndroidMainfest درج می‌شوند؛ لذا، ضرورت دارد تا دقت کافی به آنها داشته باشیم.
رشته‌هایی که در طی چند خط می‌نویسید وظیفه دارند تا مجوزهای لازم را شناسایی کرده و برای سیستم عامل توضیح دهند و اجازه می‌دهند تا فهرست مجوزها را بر روی دستگاه به کاربر نهایی نمایش دهد.
می خواهیم این رشته‌ها را به گونه‌ای دیگر تنظیم کنیم:
<string name=" label_purgeDatabase ">purge the application database </string>
<string name="permdesc_callPhone">Allows the application to purge the core database of
the information store. Malicious applications may be able to wipe your entire application
information store.</string>

مشخصه android:protectionLevel که در چند خط قبل در فایل تنظیمات درج شده است، مورد نیاز است و باید فراخوانده شود. همچنین می‌توانید یک مشخصه به نام android:permissionGroup را تعریف کنید تا خواص این مجوز را در برگیرد. اجازه بدهید تا مجوزهای سفارشی شما با مجوزهای سیستمی ارتباط برقرار کنند. لذا این ارتباط باعث بروز افزایش امنیت خواهد شد.
  برای مثال اضافه کردن مجوز purgeDatabase به صورت گروهی برای دسترسی به کارت sd صفاتی را به فایل AndroidMainfest تزریق می‌کند:
android:permissionGroup=" android.permission-group.STORAGE"
یکی از نکاتی که باید توجه داشته باشید این است که برنامه شما قبل از هر برنامه وابسته دیگری باید بر روی دستگاه نصب شود؛ چرا که اگر برنامه شما اول نصب نشود، به مشکل برخورد خواهید کرد و این مورد برای تمامی مجوزها صدق می‌کند.