예제 #1
0
        public static SymmetricAlgorithm CreateSymAlgorithm(SymAlgorithms saAlgo)
        {
            SymmetricAlgorithm saReturn;

            switch (saAlgo)
            {
            case SymAlgorithms.AES128:
                saReturn           = Rijndael.Create();
                saReturn.BlockSize = 128;
                saReturn.KeySize   = 128;
                break;

            case SymAlgorithms.AES192:
                saReturn           = Rijndael.Create();
                saReturn.BlockSize = 128;
                saReturn.KeySize   = 192;
                break;

            case SymAlgorithms.AES256:
                saReturn           = Rijndael.Create();
                saReturn.BlockSize = 128;
                saReturn.KeySize   = 256;
                break;

            case SymAlgorithms.CAST5:
                saReturn = CAST5.Create();
                break;

            case SymAlgorithms.Triple_DES:
                saReturn = TripleDES.Create();
                break;

            default:
                throw new System.Security.Cryptography.CryptographicException("The algorithm is not supported!");
            }

            return(saReturn);
        }
예제 #2
0
        public BigInteger[] GetDecryptedKeyMaterial(string strPassphrase)
        {
            BigInteger[] biKeys = new BigInteger[0];
            if (this.bIsEncrypted)
            {
                SharpPrivacy.SharpPrivacyLib.Cipher.SymmetricAlgorithm saAlgo;
                switch (this.SymmetricalAlgorithm)
                {
                case SymAlgorithms.AES128:
                    saAlgo           = Rijndael.Create();
                    saAlgo.BlockSize = 128;
                    saAlgo.KeySize   = 128;
                    break;

                case SymAlgorithms.AES192:
                    saAlgo           = Rijndael.Create();
                    saAlgo.BlockSize = 128;
                    saAlgo.KeySize   = 192;
                    break;

                case SymAlgorithms.AES256:
                    saAlgo           = Rijndael.Create();
                    saAlgo.BlockSize = 128;
                    saAlgo.KeySize   = 256;
                    break;

                case SymAlgorithms.Triple_DES:
                    saAlgo         = TripleDES.Create();
                    saAlgo.KeySize = 192;
                    break;

                case SymAlgorithms.CAST5:
                    saAlgo = CAST5.Create();
                    break;

                default:
                    throw(new System.NotSupportedException("Sorry, but the Algorithm that was used to encrypt the secret key data is not (yet) supported by SharpPrivacy!"));
                }

                saAlgo.Mode = CipherMode.CFB;
                saAlgo.Key  = this.S2KSpecifier.GetKey(strPassphrase, saAlgo.KeySize);

                if (this.PublicKey.Version == PublicKeyPacketVersionNumbers.v3)
                {
                    throw(new System.NotImplementedException("Sorry, but we have not yet implemented the decryption of v3 keys!"));
                }
                else if (this.PublicKey.Version == PublicKeyPacketVersionNumbers.v4)
                {
                    //In v4 keys, everything - including mpi headers and checksum
                    //is encrypted. Should be a heck of a lot easier than for
                    //v3 keys.

                    saAlgo.IV      = this.InitialVector;
                    saAlgo.Padding = PaddingMode.None;

                    byte[]           bOutput = new byte[this.bEncryptedKeyMaterial.Length];
                    ICryptoTransform ictDec  = saAlgo.CreateDecryptor();
                    ictDec.TransformBlock(bEncryptedKeyMaterial, 0, bEncryptedKeyMaterial.Length, ref bOutput, 0);

                    int iCurrentChecksum = 0;
                    for (int i = 0; i < bOutput.Length; i++)
                    {
                        iCurrentChecksum = (iCurrentChecksum + bOutput[i]) % 65536;
                    }

                    if (pkpPublicKey.Algorithm == AsymAlgorithms.DSA ||
                        pkpPublicKey.Algorithm == AsymAlgorithms.ElGama_Encrypt_Sign ||
                        pkpPublicKey.Algorithm == AsymAlgorithms.ElGamal_Encrypt_Only)
                    {
                        biKeys = new BigInteger[1];
                        try {
                            biKeys = BigInteger.ParseMPIs(bOutput, 1);
                        } catch (Exception) {
                            throw new Exception("Invalid Passphrase!");
                        }
                    }
                    else if (pkpPublicKey.Algorithm == AsymAlgorithms.RSA_Encrypt_Only ||
                             pkpPublicKey.Algorithm == AsymAlgorithms.RSA_Encrypt_Sign ||
                             pkpPublicKey.Algorithm == AsymAlgorithms.RSA_Sign_Only)
                    {
                        biKeys = new BigInteger[4];
                        try {
                            biKeys = BigInteger.ParseMPIs(bOutput, 4);
                        } catch (Exception) {
                            throw new Exception("Invalid Passphrase!");
                        }
                    }
                }
            }
            else
            {
                //Key Material is not encrypted anyway
                biKeys = this.DecryptedKeyMaterial;
            }

            return(biKeys);
        }
예제 #3
0
        public void EncryptKeyMaterial(BigInteger[] biGivenKeyMaterial, string strPassphrase)
        {
            this.biDecryptedKeyMaterial = biGivenKeyMaterial;
            if (!bIsEncrypted)
            {
                return;
            }

            if (this.PublicKey.Version == PublicKeyPacketVersionNumbers.v4)
            {
                int iKeyMaterialLength = 0;
                for (int i = 0; i < this.biDecryptedKeyMaterial.Length; i++)
                {
                    iKeyMaterialLength += biDecryptedKeyMaterial[i].GetMPI().Length;
                }

                byte[] bData = new byte[iKeyMaterialLength + 2];
                int    iPos  = 0;
                for (int i = 0; i < this.biDecryptedKeyMaterial.Length; i++)
                {
                    byte[] bMPI = biDecryptedKeyMaterial[i].GetMPI();
                    Array.Copy(bMPI, 0, bData, iPos, bMPI.Length);
                    iPos += bMPI.Length;
                }

                int iChecksum = 0;
                for (int i = 0; i < bData.Length - 2; i++)
                {
                    iChecksum = (iChecksum + bData[i]) % 65536;
                }

                bData[iPos++] = (byte)((iChecksum >> 8) & 0xFF);
                bData[iPos++] = (byte)(iChecksum & 0xFF);

                SharpPrivacy.SharpPrivacyLib.Cipher.SymmetricAlgorithm saAlgo;
                switch (this.SymmetricalAlgorithm)
                {
                case SymAlgorithms.AES128:
                    saAlgo           = Rijndael.Create();
                    saAlgo.BlockSize = 128;
                    saAlgo.KeySize   = 128;
                    break;

                case SymAlgorithms.AES192:
                    saAlgo           = Rijndael.Create();
                    saAlgo.BlockSize = 128;
                    saAlgo.KeySize   = 192;
                    break;

                case SymAlgorithms.AES256:
                    saAlgo           = Rijndael.Create();
                    saAlgo.BlockSize = 128;
                    saAlgo.KeySize   = 256;
                    break;

                case SymAlgorithms.Triple_DES:
                    saAlgo         = TripleDES.Create();
                    saAlgo.KeySize = 192;
                    break;

                case SymAlgorithms.CAST5:
                    saAlgo = CAST5.Create();
                    break;

                default:
                    throw(new System.NotSupportedException("Sorry, but the Algorithm that was used to encrypt the secret key data is not (yet) supported by SharpPrivacy!"));
                }

                saAlgo.Mode    = CipherMode.CFB;
                saAlgo.Key     = this.S2KSpecifier.GetKey(strPassphrase, saAlgo.KeySize);
                saAlgo.IV      = this.InitialVector;
                saAlgo.Padding = PaddingMode.None;

                byte[]           bOutput = new byte[bData.Length];
                ICryptoTransform ictEnc  = saAlgo.CreateEncryptor();
                ictEnc.TransformBlock(bData, 0, bData.Length, ref bOutput, 0);

                byte[] bTmp = new byte[bData.Length];
                Array.Copy(bOutput, 0, bTmp, 0, bTmp.Length);
                bOutput = bTmp;

                if (bOutput.Length != bData.Length)
                {
                    throw new Exception("Encryption of the secret Key material did not work correctly. Look at the file SecretKeyPacket, function EncryptKeyMaterial()");
                }

                bEncryptedKeyMaterial = bOutput;
            }
            else
            {
                throw new Exception("Sorry, but we don't support v3 secret keys so far!");
            }
            this.bIsUpdated = true;
        }