Esempio n. 1
0
        /// <summary>
        /// Generates a cert request (csr).
        /// </summary>
        /// <param name="keyPair">Is the public / private key pair of the
        /// client generating a cert request.</param>
        /// <param name="country">Is the optional country value of the client generating
        /// a cert request.</param>
        /// <param name="state">Is the optional state name value of the client generating
        /// a cert request.</param>
        /// <param name="city">Is the optional city name value of the client generating
        /// a cert request.</param>
        /// <param name="orgName">Is the optional organization name value of the
        /// client generating a cert request.</param>
        /// <param name="email">Is the optional email value of the client generating
        /// a cert request.</param>
        /// <param name="userId">Is the compulsory user ID value of the client generating
        /// a cert request.</param>
        /// <returns>Certificate request</returns>
        /// <exception cref="UserIDException">Throws this exception if the user ID
        /// is set to null.</exception>
        public static byte[] CreateCsr(RsaKeyPair keyPair,
                                       RegionInfo country,
                                       string state,
                                       string city,
                                       string orgName,
                                       string email,
                                       Guid userId)
        {
            IDictionary attributes = new Hashtable();

            attributes.Add(X509Name.C, country?.TwoLetterISORegionName ?? "");
            attributes.Add(X509Name.ST, state ?? "");
            attributes.Add(X509Name.L, city ?? "");
            attributes.Add(X509Name.O, orgName ?? "");
            attributes.Add(X509Name.EmailAddress, email ?? "");
            if (userId == null)
            {
                throw new Exception();
            }
            attributes.Add(X509Name.CN, userId.ToString());

            X509Name subject = new X509Name(new ArrayList(attributes.Keys), attributes);

            ISignatureFactory signatureFactory = new Asn1SignatureFactory(HASH_ENCRYPTION_ALGORITHM,
                                                                          keyPair.PrivateKeyParameters,
                                                                          new SecureRandom());

            Pkcs10CertificationRequest csr = new Pkcs10CertificationRequest(signatureFactory,
                                                                            subject,
                                                                            keyPair.PublicKeyParameters,
                                                                            null);

            return(SerializeCsr(csr));
        }
        /// <summary>
        /// Method performing asymmetric encryption with the private key.
        /// </summary>
        /// <param name="data">Data to encrypt.</param>
        /// <param name="keyPair">Instance of <see cref="RsaKeyPair"/>
        /// containing the private key.</param>
        /// <param name="encryptOrDecrypt">Flag indicating if an encryption or
        /// decryption is performed.</param>
        /// <returns>Encrypted or decrypted base64 encoded data.</returns>
        private byte[] RsaCryptingWithPrivate(byte[] data, RsaKeyPair keyPair, bool encryptOrDecrypt)
        {
            Pkcs1Encoding          cryptEngine = new Pkcs1Encoding(new RsaEngine());
            AsymmetricKeyParameter keyParam    = keyPair.PrivateKey;

            cryptEngine.Init(encryptOrDecrypt, keyParam);
            return(cryptEngine.ProcessBlock(data, 0, data.Length));
        }
        /// <summary>
        /// RSA decrypts a message with the private key. The message to decrypt
        /// must not surpass the maximum message length. As the method <see
        /// cref="RsaEncryptWithPublic"/> takes the message length into
        /// consideration, no message length checking is performed inside this
        /// method. Hence, when decrypting messages which was encrypted with a
        /// different message, the method will return null if the limitation is
        /// surpassed.
        /// </summary>
        /// <param name="encryptedText">Base 64 encoded encrypted text.</param>
        /// <param name="keyPair">Instance of <see cref="RsaKeyPair"/>
        /// containing the public key.</param>
        /// <returns>UTF-8 decrypted data or null if the message is too
        /// long.</returns>
        public string RsaDecryptWithPrivate(string encryptedText, RsaKeyPair keyPair)
        {
            byte[] data = Convert.FromBase64String(encryptedText);
            if (CheckMessageLength(data, keyPair.PrivateKeyParameters.Modulus.BitLength))
            {
                byte[] decrypted = RsaCryptingWithPrivate(data, keyPair, false);
                return(Encoding.UTF8.GetString(decrypted));
            }

            return(null);
        }
        /// <summary>
        /// RSA encrypts any sized message with the private key. The RSA
        /// asymmetric encryption can only encrypt messages of a maximum size.
        /// The size is dependent on the private key length and consequently,
        /// this method splits the message to encrypt into fragments meeting
        /// this requirement.
        /// </summary>
        /// <param name="clearText">Data to encrypt.</param>
        /// <param name="keyPair">Instance of <see cref="RsaKeyPair"/>
        /// containing the public key.</param>
        /// <returns>Base 64 encrypted data.</returns>
        public ArrayList RsaEncryptWithPrivate(string clearText, RsaKeyPair keyPair)
        {
            byte[] data = Encoding.UTF8.GetBytes(clearText);
            // determine if the message to encrypt is too long and hence must be split-up
            byte[][]  messageBlocks = GetMessageBlocks(keyPair.PrivateKeyParameters.Modulus.BitLength, data);
            ArrayList list          = new ArrayList();

            for (int i = 0; i < messageBlocks.Length; i++)
            {
                byte[] encrypted = RsaCryptingWithPrivate(messageBlocks[i], keyPair, true);
                list.Add(Convert.ToBase64String(encrypted));
            }

            return(list);
        }
        static void Main(string[] args)
        {
            //RsaKeyPair keyRing = new RsaKeyPair("1234", true);
            //Guid guid = Guid.NewGuid();
            //byte[] pemCsr = Certificator.CreateCsr(keyRing,
            //                                       RegionInfo.CurrentRegion,
            //                                       "vd", "cheseaux-noréaz", "sigi", "sigi@nowhere", guid);
            //X509Certificate cert = new Certificator().SignCsr(pemCsr);
            //keyRing.Certificate = cert;
            //keyRing.Save(cert);

            RsaKeyPair keyRing = new RsaKeyPair("1234");

            //var remainingDays = Certificator.GetRemainingDays(keyRing.Certificate);
            //var IsExpired = Certificator.IsExpired(keyRing.Certificate);
            //var IsSignedByServer = new Certificator().IsSignedByServer(keyRing.Certificate);

            string plainMessage = "I already have an RSACryptoServiceProvider loaded with private/public keys. From some research " +
                                  "it's my understanding that I would need to do the faster, symmetric encryption to encrypt the data " +
                                  "and then the slower, asymmetric encryption using the certificate to encrypt the key. What I'm having " +
                                  "trouble with is weaving all the online examples together into an encrypt/decrypt function like for signing." +
                                  "This is a message to encrypt 1...2...3";
            //string plainMessage = "This is a message to encrypt...";

            var data = Encoding.UTF8.GetBytes(plainMessage);
            var res  = Signer.GetSignature(data, null, null, keyRing);
            // positive test
            bool isValid = Signer.ValidateSignature(data, res.Signature, keyRing.Certificate);

            isValid = Signer.ValidateSignature(plainMessage, res.Signature, keyRing.Certificate);
            // negative test
            data[data.Length - 2] = 0;
            bool notValid = true;

            notValid     = Signer.ValidateSignature(data, res.Signature, keyRing.Certificate);
            plainMessage = plainMessage.Replace('2', '9');
            plainMessage = plainMessage.Substring(0, plainMessage.Length - 2);
            notValid     = Signer.ValidateSignature(data, res.Signature, keyRing.Certificate);

            ArrayList encrytedMessages;
            string    result    = "";
            Encryptor encryptor = new Encryptor();

            // encrypt with pubKey and decrypt with privKey
            Console.WriteLine("ENCRYPT with PUBLIC KEY and DECRYPT with PRIVATE KEY");
            encrytedMessages = encryptor.RsaEncryptWithPublic(plainMessage, keyRing);
            foreach (var encrytedMessage in encrytedMessages)
            {
                result = encryptor.RsaDecryptWithPrivate((string)encrytedMessage, keyRing);
                Console.WriteLine(result);
            }

            // encrypt with privKey and decrypt with pubKey - THIS WORKS
            Console.WriteLine("ENCRYPT with PRIVATE KEY and DECRYPT with PUBLIC KEY");
            encrytedMessages = encryptor.RsaEncryptWithPrivate(plainMessage, keyRing);
            foreach (var encrytedMessage in encrytedMessages)
            {
                result = encryptor.RsaDecryptWithPublic((string)encrytedMessage, keyRing);
                Console.WriteLine(result);
            }

            Console.ReadLine();
        }