コード例 #1
0
        /// <summary>
        /// Encryptes the session key stored in the SessionKey property
        /// and saves the results in the EncryptedSessionKey property.
        /// </summary>
        /// <remarks>This method also calles EncodeSessionKey so that it
        /// does not have been called before calling EncryptSessionKey.
        /// <p></p>
        /// Please note: calling this function takes some time, because
        /// asymmetrical encryption takes some time!
        /// </remarks>
        /// <param name="pkpPacket">An PublicKeyPacket to which
        /// the sessionkey should be encrypted to.</param>
        public void EncryptSessionKey(PublicKeyPacket pkpPacket)
        {
            EncodeSessionKey(pkpPacket.KeyMaterial[0].bitCount());

            AsymmetricCipher acCipher = new RSA();

            switch (aaPublicAlgorithm)
            {
            case AsymAlgorithms.ElGama_Encrypt_Sign:
            case AsymAlgorithms.ElGamal_Encrypt_Only:
                acCipher = new ElGamal();
                break;

            case AsymAlgorithms.RSA_Encrypt_Only:
            case AsymAlgorithms.RSA_Encrypt_Sign:
                acCipher = new RSA();
                break;

            default:
                throw new System.Exception("The chosen public key algorithm is not yet implemented!");
            }

            this.bIsUpdated       = true;
            biEncryptedSessionKey = acCipher.Encrypt(new BigInteger(this.bEncodedSessionKey), pkpPacket);
        }
コード例 #2
0
ファイル: DSA.cs プロジェクト: kabili207/SharpPrivacy
 /// <summary>
 /// Encryption is not supported for DSA. If you call this function,
 /// an Exception will be thrown.
 /// </summary>
 /// <remarks>
 /// Encryption is not supported for DSA. If you call this function,
 /// an Exception will be thrown.
 /// </remarks>
 public override BigInteger[] Encrypt(BigInteger biPlain, PublicKeyPacket pkpKey)
 {
     throw(new Exception("The DSA cipher cannot be used for encryption"));
 }
コード例 #3
0
ファイル: DSA.cs プロジェクト: kabili207/SharpPrivacy
        private DSA_Public_Key ParsePublicKey(PublicKeyPacket pkpKey)
        {
            DSA_Public_Key dpkKey = new DSA_Public_Key();

            if (pkpKey.Algorithm != AsymAlgorithms.DSA)
                throw(new System.ArgumentException("The given key is not supposed to be used with DSA!"));

            if (pkpKey.KeyMaterial.Length != 4)
                throw(new System.ArgumentException("The given key is not a valid key for DSA!"));

            dpkKey.p = pkpKey.KeyMaterial[0];
            dpkKey.q = pkpKey.KeyMaterial[1];
            dpkKey.g = pkpKey.KeyMaterial[2];
            dpkKey.y = pkpKey.KeyMaterial[3];

            return dpkKey;
        }
コード例 #4
0
ファイル: DSA.cs プロジェクト: kabili207/SharpPrivacy
        /// <summary>
        /// Public key operation. Verifies biSignature with the keydata
        /// in the given public key packet and returns true if the signature
        /// is valid.
        /// </summary>
        /// <param name="biSignature">The signature that is about to
        /// be verified</param>
        /// <param name="biHash">The hash value of the signed message.</param>
        /// <param name="pkpKey">The public key packet with the key
        /// material for the verification.</param>
        /// <returns>True if the signature is valid, otherwise 
        /// false</returns>
        /// <remarks>No remarks</remarks>
        public override bool Verify(BigInteger[] biSignature, BigInteger biHash, PublicKeyPacket pkpKey)
        {
            if (biSignature == null)
                throw new ArgumentNullException("rgbSignature");

            DSA_Public_Key dpkKey = new DSA_Public_Key();
            dpkKey = ParsePublicKey(pkpKey);

            try {
                BigInteger m = biHash;
                BigInteger r = biSignature[0];
                BigInteger s = biSignature[1];

                if ((r < 0) || (dpkKey.q <= r))
                    return false;

                if ((s < 0) || (dpkKey.q <= s))
                    return false;

                BigInteger w = s.modInverse(dpkKey.q);
                BigInteger u1 = m * w % dpkKey.q;
                BigInteger u2 = r * w % dpkKey.q;

                u1 = dpkKey.g.modPow(u1, dpkKey.p);
                u2 = dpkKey.y.modPow(u2, dpkKey.p);

                BigInteger v = ((u1 * u2 % dpkKey.p) % dpkKey.q);
                return (v == r);
            } catch {
                throw new CryptographicException();
            }
        }
コード例 #5
0
        /// <summary>
        /// Verifies the data given as parameter with the given public key.
        /// </summary>
        /// <remarks>
        /// <para>The function calculates a message digest over the given signature
        /// data and verifies the digest with the digest stored in the
        /// signature packet.</para>
        /// <para>The results of the verify operation are directly stored
        /// in the SignatureStatus property of this class.</para>
        /// </remarks>
        /// <param name="bSignedData">The data that is to be verified.</param>
        /// <param name="pkpKey">The key that is to verify the signature</param>
        public void Verify(byte[] bSignedData, PublicKeyPacket pkpKey)
        {
            System.Security.Cryptography.HashAlgorithm haVerifyer;
            AsymmetricCipher acVerifyer;

            switch (this.HashAlgorithm) {
                case HashAlgorithms.MD5:
                    haVerifyer = System.Security.Cryptography.MD5.Create();
                    break;
                case HashAlgorithms.SHA1:
                    haVerifyer = System.Security.Cryptography.SHA1.Create();
                    break;
                default:
                    throw(new System.Exception("Currently only MD5 and SHA1 are implemented as hash algorithms!"));
            }

            switch (this.SignatureAlgorithm) {
                case AsymAlgorithms.DSA:
                    acVerifyer = new SharpPrivacy.SharpPrivacyLib.Cipher.DSA();
                    break;
                case AsymAlgorithms.RSA_Encrypt_Sign:
                case AsymAlgorithms.RSA_Sign_Only:
                    acVerifyer = new SharpPrivacy.SharpPrivacyLib.Cipher.RSA();
                    break;
                default:
                    throw(new System.Exception("Currently only DSA and RSA are implemented as signature algorithms!"));
            }

            byte[] bSignature = new byte[0];
            int iCounter = 0;
            if (this.Version <= SignaturePacketVersionNumbers.v3) {
                bSignature = new byte[5];

                bSignature[iCounter++] = (byte)this.SignatureType;
                long lTime = (dtTimeCreated.Ticks - new DateTime(1970, 1, 1).Ticks)/10000000;
                bSignature[iCounter++] = (byte)((lTime >> 24) & 0xFF);
                bSignature[iCounter++] = (byte)((lTime >> 16) & 0xFF);
                bSignature[iCounter++] = (byte)((lTime >> 8) & 0xFF);
                bSignature[iCounter++] = (byte)(lTime & 0xFF);
            } else {
                //Hashed Subpackets Length
                int lHashedSubPacketLength = 0;
                for (int i=0; i<this.HashedSubPackets.Length; i++) {
                    lHashedSubPacketLength += this.HashedSubPackets[i].Generate().Length;
                }

                bSignature = new byte[lHashedSubPacketLength + 12];
                bSignature[iCounter++] = 4; // Version
                bSignature[iCounter++] = (byte)this.SignatureType;
                bSignature[iCounter++] = (byte)this.SignatureAlgorithm;
                bSignature[iCounter++] = (byte)this.HashAlgorithm;

                //Hashed Subpackets
                bSignature[iCounter++] = (byte)((lHashedSubPacketLength >> 8) & 0xFF);
                bSignature[iCounter++] = (byte)(lHashedSubPacketLength & 0xFF);
                for (int i=0; i<this.HashedSubPackets.Length; i++) {
                    byte[] bSubPacket = this.HashedSubPackets[i].Generate();
                    Array.Copy(bSubPacket, 0, bSignature, iCounter, bSubPacket.Length);
                    iCounter += bSubPacket.Length;
                }

                //Final Trailer of 6 bytes
                bSignature[iCounter++] = 0x04;
                bSignature[iCounter++] = 0xFF;
                bSignature[iCounter++] = (byte)(((lHashedSubPacketLength+6) >> 24) & 0xFF);
                bSignature[iCounter++] = (byte)(((lHashedSubPacketLength+6) >> 16) & 0xFF);
                bSignature[iCounter++] = (byte)(((lHashedSubPacketLength+6) >> 8) & 0xFF);
                bSignature[iCounter++] = (byte)((lHashedSubPacketLength+6) & 0xFF);

            }

            byte[] bData = new byte[bSignedData.Length + bSignature.Length];
            Array.Copy(bSignedData, bData, bSignedData.Length);
            Array.Copy(bSignature, 0, bData, bSignedData.Length, bSignature.Length);

            byte[] bHash = haVerifyer.ComputeHash(bData);
            BigInteger biHash = new BigInteger(bHash);

            //PKCS1 Encode the hash
            if (this.SignatureAlgorithm != AsymAlgorithms.DSA) {

                // We encode the MD in this way:
                //  0  A PAD(n bytes)   0  ASN(asnlen bytes)  MD(len bytes)
                // PAD consists of FF bytes.
                byte[] bASN = new byte[0];

                switch (this.HashAlgorithm) {
                    case HashAlgorithms.MD5:
                        bASN = new byte[] {0x30, 0x20, 0x30, 0x0C, 0x06, 0x08,
                                           0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
                                           0x02, 0x05, 0x05, 0x00, 0x04, 0x10};
                        break;
                    case HashAlgorithms.SHA1:
                        bASN = new byte[] {0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
                                           0x2b, 0x0E, 0x03, 0x02, 0x1A, 0x05,
                                           0x00, 0x04, 0x14};
                        break;
                }

                int iFrameSize = (pkpKey.KeyMaterial[0].bitCount() + 7) / 8;
                byte[] bFrame = new byte[iFrameSize];
                int iASNCounter = 0;

                bFrame[iASNCounter++] = 0;
                bFrame[iASNCounter++] = 1;
                int iFFLength = iFrameSize - bHash.Length - bASN.Length - 3;
                for (int i=0; i<iFFLength; i++) {
                    bFrame[iASNCounter++] = 0xFF;
                }
                bFrame[iASNCounter++] = 0;
                Array.Copy(bASN, 0, bFrame, iASNCounter, bASN.Length);
                iASNCounter += bASN.Length;
                Array.Copy(bHash, 0, bFrame, iASNCounter, bHash.Length);
                biHash = new BigInteger(bFrame);
            }

            if (acVerifyer.Verify(this.Signature, biHash, pkpKey)) {
                ssSignatureStatus = SignatureStatusTypes.Valid;
            } else {
                ssSignatureStatus = SignatureStatusTypes.Invalid;
            }
        }
コード例 #6
0
ファイル: ElGamal.cs プロジェクト: kabili207/SharpPrivacy
 public override bool Verify(BigInteger[] biSignature, BigInteger biHash, PublicKeyPacket pkpKey)
 {
     throw new System.NotImplementedException("Signatures with ElGamal keys are not yet implemented!");
 }
コード例 #7
0
ファイル: RSA.cs プロジェクト: kabili207/SharpPrivacy
        /// <summary>
        /// Public key operation. Encrypt biPlain with the keydata
        /// in the given public key packet. Result of c = m^e mod n
        /// is returned.
        /// </summary>
        /// <param name="biPlain">The plaintext that is about to
        /// be encrypted</param>
        /// <param name="pkpKey">The public key packet with the key
        /// material for the encryption</param>
        /// <returns>c = m^e mod n, the encrypted plaintext. The return
        /// value is given as an array of biginteger. The length of the 
        /// array is 1 and only return[0] has a value.</returns>
        /// <remarks>No remarks.</remarks>
        public override BigInteger[] Encrypt(BigInteger biPlain, PublicKeyPacket pkpKey)
        {
            RSA_Public_Key rpkKey = new RSA_Public_Key();

            if ((pkpKey.Algorithm != AsymAlgorithms.RSA_Encrypt_Only) &&
                (pkpKey.Algorithm != AsymAlgorithms.RSA_Encrypt_Sign)) {
                throw new System.ArgumentException("This public key is not supposed to be used for RSA encryption.");
            }
            if (pkpKey.KeyMaterial.Length != 2) {
                throw new System.ArgumentException("This is not a valid RSA Key");
            }

            rpkKey.n = pkpKey.KeyMaterial[0];
            rpkKey.e = pkpKey.KeyMaterial[1];

            return Encrypt(biPlain, rpkKey);
        }
コード例 #8
0
ファイル: Packet.cs プロジェクト: deycrypt/SharpPrivacy
        /// <summary>
        /// Parses a single packet out of the given binary
        /// data. Even if there are more than one packets in the byte
        /// array, only the first packet is returned.
        /// </summary>
        /// <param name="bBinaryData">A byte array containing a set
        /// of OpenPGP packets</param>
        /// <returns>Returns an single OpenPGP packets</returns>
        /// <remarks>No remarks</remarks>
        public virtual Packet ParsePacket(byte[] bBinaryData)
        {
            Packet pReturnPacket = new Packet();

            if ((bBinaryData[0] & 0xC0) == 0xC0)
            {
                pfFormat = PacketFormats.New;
            }
            else if ((bBinaryData[0] & 0xC0) == 0x80)
            {
                pfFormat = PacketFormats.Old;
            }
            else
            {
                throw(new ArgumentException("This is not a valid OpenPGP Packet"));
            }


            if (pfFormat == PacketFormats.New)
            {
                int iBinaryDataPos = 1;
                ctContent = (ContentTypes)(bBinaryData[0] & 0x3F);
                lLength   = bBinaryData[1];
                bBody     = new byte[0];
                int iHeaderLength = 1;
                //partial body lengths
                while ((lLength > 223) && (lLength < 255))
                {
                    iBinaryDataPos += 1;
                    iHeaderLength++;
                    int lPartialBody = 1 << ((int)(lLength & 0x1F));
                    int lOldLength   = 0;
                    if (bBody.Length > 0)
                    {
                        byte[] bOldBody = new byte[bBody.Length];
                        bBody.CopyTo(bOldBody, 0);
                        bBody = new byte[bOldBody.Length + lPartialBody];
                        bOldBody.CopyTo(bBody, 0);
                        lOldLength = bBody.Length;
                    }
                    else
                    {
                        bBody = new byte[lPartialBody];
                    }
                    Array.Copy(bBinaryData, iBinaryDataPos, bBody, bBody.Length - lPartialBody, lPartialBody);
                    lLength         = bBinaryData[iBinaryDataPos + lPartialBody];
                    iBinaryDataPos += lPartialBody;
                }                 //partial bodies must end with a normal header!
                if (lLength < 192)
                {
                    iHeaderLength++;
                    bHeader = new byte[iHeaderLength];
                    if (bBody.Length == 0)
                    {
                        Array.Copy(bBinaryData, 0, bHeader, 0, 2);
                        iBinaryDataPos = 1;
                    }
                    byte[] bOldBody = new byte[bBody.Length];
                    bBody.CopyTo(bOldBody, 0);
                    bBody = new byte[bOldBody.Length + lLength];
                    bOldBody.CopyTo(bBody, 0);
                    Array.Copy(bBinaryData, iBinaryDataPos + 1, bBody, bBody.Length - (int)lLength, (int)lLength);
                }
                else if ((lLength > 191) && (lLength < 224))
                {
                    iHeaderLength += 2;
                    bHeader        = new byte[iHeaderLength];
                    if (bBody.Length == 0)
                    {
                        Array.Copy(bBinaryData, 0, bHeader, 0, 3);
                        iBinaryDataPos = 1;
                    }
                    lLength = ((bBinaryData[iBinaryDataPos++] - 192) << 8) + bBinaryData[iBinaryDataPos++] + 192;
                    byte[] bOldBody = new byte[bBody.Length];
                    bBody.CopyTo(bOldBody, 0);
                    bBody = new byte[bOldBody.Length + lLength];
                    bOldBody.CopyTo(bBody, 0);
                    Array.Copy(bBinaryData, iBinaryDataPos, bBody, bBody.Length - (int)lLength, (int)lLength);
                }
                else if (lLength == 255)
                {
                    iHeaderLength += 5;
                    bHeader        = new byte[iHeaderLength];
                    if (bBody.Length == 0)
                    {
                        Array.Copy(bBinaryData, 0, bHeader, 0, 6);
                        iBinaryDataPos = 1;
                    }
                    lLength = (bBinaryData[iBinaryDataPos++] << 24) ^ (bBinaryData[iBinaryDataPos++] << 16) ^
                              (bBinaryData[iBinaryDataPos++] << 8) ^ bBinaryData[iBinaryDataPos++];
                    byte[] bOldBody = new byte[bBody.Length];
                    bBody.CopyTo(bOldBody, 0);
                    bBody = new byte[bOldBody.Length + lLength];
                    bOldBody.CopyTo(bBody, 0);
                    Array.Copy(bBinaryData, iBinaryDataPos, bBody, bBody.Length - (int)lLength, (int)lLength);
                }
            }
            else
            {
                ctContent = (ContentTypes)((bBinaryData[0] & 0x3C) >> 2);
                switch (bBinaryData[0] & 0x03)
                {
                case 0:
                    lLength = bBinaryData[1];
                    bHeader = new byte[2];
                    break;

                case 1:
                    lLength = (bBinaryData[1] << 8) ^ (bBinaryData[2]);
                    bHeader = new byte[3];
                    break;

                case 2:
                    lLength = (bBinaryData[1] << 16) ^ (bBinaryData[2] << 8) ^
                              (bBinaryData[3]);
                    bHeader = new byte[4];
                    break;

                case 3:
                    throw new System.NotSupportedException("Packets of indetermined length are not supported due to security considerations!");

                default:
                    throw new System.ApplicationException("This is not a valid Packet!");
                }
                bBody = new byte[lLength];
                Array.Copy(bBinaryData, 0, bHeader, 0, bHeader.Length);
                Array.Copy(bBinaryData, bHeader.Length, bBody, 0, (int)lLength);
            }

            this.bIsUpdated = false;
            switch (ctContent)
            {
            case ContentTypes.AsymSessionKey:
                pReturnPacket = new AsymSessionKeyPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.Compressed:
                pReturnPacket = new CompressedDataPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.LiteralData:
                pReturnPacket = new LiteralDataPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.Marker:
                pReturnPacket = new Packet(this);
                //We can savly ignore Marker packets!
                //MessageBox.Show("This is a marker packet. It is not yet supported.");
                break;

            case ContentTypes.OnePassSignature:
                pReturnPacket = new OnePassSignaturePacket(this);
                //System.Windows.Forms.MessageBox.Show("This is a One Pass Signature Packet. It is not yet supported");
                break;

            //Content is Public Key Packet
            case ContentTypes.PublicKey:
                pReturnPacket = new PublicKeyPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            //Content is Public Subkey Packet. Same format as Public Key Packet
            case ContentTypes.PublicSubkey:
                pReturnPacket = new PublicKeyPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.SecretKey:
                pReturnPacket = new SecretKeyPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.SecretSubkey:
                pReturnPacket = new SecretKeyPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.Signature:
                pReturnPacket = new SignaturePacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.SymEncrypted:
                pReturnPacket = new SymmetricallyEncryptedDataPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.SymSessionKey:
                pReturnPacket = new SymSessionKeyPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.Trust:
                pReturnPacket = new Packet(this);
                //throw new Exception("This is a Trust Packet. It is not yet supported");
                break;

            case ContentTypes.UserID:
                pReturnPacket = new UserIDPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            default:
                pReturnPacket = new Packet(this);
                //throw new Exception("Sorry, but this is a packet I don't know about!");
                break;
            }

            pReturnPacket.bIsUpdated = false;
            return(pReturnPacket);
        }
コード例 #9
0
ファイル: Packet.cs プロジェクト: kabili207/SharpPrivacy
        /// <summary>
        /// Parses a single packet out of the given binary
        /// data. Even if there are more than one packets in the byte
        /// array, only the first packet is returned.
        /// </summary>
        /// <param name="bBinaryData">A byte array containing a set
        /// of OpenPGP packets</param>
        /// <returns>Returns an single OpenPGP packets</returns>
        /// <remarks>No remarks</remarks>
        public virtual Packet ParsePacket(byte[] bBinaryData)
        {
            Packet pReturnPacket = new Packet();

            if ((bBinaryData[0] & 0xC0) == 0xC0) {
                pfFormat = PacketFormats.New;
            } else if ((bBinaryData[0] & 0xC0) == 0x80) {
                pfFormat = PacketFormats.Old;
            } else {
                throw(new ArgumentException("This is not a valid OpenPGP Packet"));
            }

            if (pfFormat == PacketFormats.New) {
                int iBinaryDataPos = 1;
                ctContent = (ContentTypes)(bBinaryData[0] & 0x3F);
                lLength = bBinaryData[1];
                bBody = new byte[0];
                int iHeaderLength = 1;
                //partial body lengths
                while ((lLength > 223) && (lLength < 255)) {
                    iBinaryDataPos += 1;
                    iHeaderLength++;
                    int lPartialBody = 1 << ((int)(lLength & 0x1F));
                    int lOldLength = 0;
                    if (bBody.Length > 0) {
                        byte[] bOldBody = new byte[bBody.Length];
                        bBody.CopyTo(bOldBody, 0);
                        bBody = new byte[bOldBody.Length + lPartialBody];
                        bOldBody.CopyTo(bBody, 0);
                        lOldLength = bBody.Length;
                    } else {
                        bBody = new byte[lPartialBody];
                    }
                    Array.Copy(bBinaryData, iBinaryDataPos, bBody, bBody.Length - lPartialBody, lPartialBody);
                    lLength = bBinaryData[iBinaryDataPos + lPartialBody];
                    iBinaryDataPos += lPartialBody;
                } //partial bodies must end with a normal header!
                if (lLength < 192) {
                    iHeaderLength++;
                    bHeader = new byte[iHeaderLength];
                    if (bBody.Length == 0) {
                        Array.Copy(bBinaryData, 0, bHeader, 0, 2);
                        iBinaryDataPos = 1;
                    }
                    byte[] bOldBody = new byte[bBody.Length];
                    bBody.CopyTo(bOldBody, 0);
                    bBody = new byte[bOldBody.Length + lLength];
                    bOldBody.CopyTo(bBody, 0);
                    Array.Copy(bBinaryData, iBinaryDataPos + 1, bBody, bBody.Length - (int)lLength, (int)lLength);
                } else if ((lLength > 191) && (lLength < 224)) {
                    iHeaderLength += 2;
                    bHeader = new byte[iHeaderLength];
                    if (bBody.Length == 0) {
                        Array.Copy(bBinaryData, 0, bHeader, 0, 3);
                        iBinaryDataPos = 1;
                    }
                    lLength = ((bBinaryData[iBinaryDataPos++] - 192) << 8) + bBinaryData[iBinaryDataPos++] + 192;
                    byte[] bOldBody = new byte[bBody.Length];
                    bBody.CopyTo(bOldBody, 0);
                    bBody = new byte[bOldBody.Length + lLength];
                    bOldBody.CopyTo(bBody, 0);
                    Array.Copy(bBinaryData, iBinaryDataPos, bBody, bBody.Length - (int)lLength, (int)lLength);
                } else if (lLength == 255) {
                    iHeaderLength += 5;
                    bHeader = new byte[iHeaderLength];
                    if (bBody.Length == 0) {
                        Array.Copy(bBinaryData, 0, bHeader, 0, 6);
                        iBinaryDataPos = 1;
                    }
                    lLength = (bBinaryData[iBinaryDataPos++] << 24) ^ (bBinaryData[iBinaryDataPos++] << 16) ^
                              (bBinaryData[iBinaryDataPos++] << 8) ^ bBinaryData[iBinaryDataPos++];
                    byte[] bOldBody = new byte[bBody.Length];
                    bBody.CopyTo(bOldBody, 0);
                    bBody = new byte[bOldBody.Length + lLength];
                    bOldBody.CopyTo(bBody, 0);
                    Array.Copy(bBinaryData, iBinaryDataPos, bBody, bBody.Length - (int)lLength, (int)lLength);
                }

            } else {
                ctContent = (ContentTypes)((bBinaryData[0] & 0x3C) >> 2);
                switch (bBinaryData[0] & 0x03) {
                    case 0:
                        lLength = bBinaryData[1];
                        bHeader = new byte[2];
                        break;
                    case 1:
                        lLength = (bBinaryData[1] << 8) ^ (bBinaryData[2]);
                        bHeader = new byte[3];
                        break;
                    case 2:
                        lLength = (bBinaryData[1] << 16) ^ (bBinaryData[2] << 8) ^
                                  (bBinaryData[3]);
                        bHeader = new byte[4];
                        break;
                    case 3:
                        throw new System.NotSupportedException("Packets of indetermined length are not supported due to security considerations!");
                    default:
                        throw new System.ApplicationException("This is not a valid Packet!");
                }
                bBody = new byte[lLength];
                Array.Copy(bBinaryData, 0, bHeader, 0, bHeader.Length);
                Array.Copy(bBinaryData, bHeader.Length, bBody, 0, (int)lLength);
            }

            this.bIsUpdated = false;
            switch (ctContent) {
                case ContentTypes.AsymSessionKey:
                    pReturnPacket = new AsymSessionKeyPacket(this);
                    pReturnPacket = pReturnPacket.ParsePacket(bBody);
                    break;
                case ContentTypes.Compressed:
                    pReturnPacket = new CompressedDataPacket(this);
                    pReturnPacket = pReturnPacket.ParsePacket(bBody);
                    break;
                case ContentTypes.LiteralData:
                    pReturnPacket = new LiteralDataPacket(this);
                    pReturnPacket = pReturnPacket.ParsePacket(bBody);
                    break;
                case ContentTypes.Marker:
                    pReturnPacket = new Packet(this);
                    //We can savly ignore Marker packets!
                    //MessageBox.Show("This is a marker packet. It is not yet supported.");
                    break;
                case ContentTypes.OnePassSignature:
                    pReturnPacket = new OnePassSignaturePacket(this);
                    //System.Windows.Forms.MessageBox.Show("This is a One Pass Signature Packet. It is not yet supported");
                    break;
                //Content is Public Key Packet
                case ContentTypes.PublicKey:
                    pReturnPacket = new PublicKeyPacket(this);
                    pReturnPacket = pReturnPacket.ParsePacket(bBody);
                    break;
                //Content is Public Subkey Packet. Same format as Public Key Packet
                case ContentTypes.PublicSubkey:
                    pReturnPacket = new PublicKeyPacket(this);
                    pReturnPacket = pReturnPacket.ParsePacket(bBody);
                    break;
                case ContentTypes.SecretKey:
                    pReturnPacket = new SecretKeyPacket(this);
                    pReturnPacket = pReturnPacket.ParsePacket(bBody);
                    break;
                case ContentTypes.SecretSubkey:
                    pReturnPacket = new SecretKeyPacket(this);
                    pReturnPacket = pReturnPacket.ParsePacket(bBody);
                    break;
                case ContentTypes.Signature:
                    pReturnPacket = new SignaturePacket(this);
                    pReturnPacket = pReturnPacket.ParsePacket(bBody);
                    break;
                case ContentTypes.SymEncrypted:
                    pReturnPacket = new SymmetricallyEncryptedDataPacket(this);
                    pReturnPacket = pReturnPacket.ParsePacket(bBody);
                    break;
                case ContentTypes.SymSessionKey:
                    pReturnPacket = new SymSessionKeyPacket(this);
                    pReturnPacket = pReturnPacket.ParsePacket(bBody);
                    break;
                case ContentTypes.Trust:
                    pReturnPacket = new Packet(this);
                    //throw new Exception("This is a Trust Packet. It is not yet supported");
                    break;
                case ContentTypes.UserID:
                    pReturnPacket = new UserIDPacket(this);
                    pReturnPacket = pReturnPacket.ParsePacket(bBody);
                    break;
                default:
                    pReturnPacket = new Packet(this);
                    //throw new Exception("Sorry, but this is a packet I don't know about!");
                    break;
            }

            pReturnPacket.bIsUpdated = false;
            return pReturnPacket;
        }
コード例 #10
0
        /// <summary>
        /// Verifies the data given as parameter with the given public key.
        /// </summary>
        /// <remarks>
        /// <para>The function calculates a message digest over the given signature
        /// data and verifies the digest with the digest stored in the
        /// signature packet.</para>
        /// <para>The results of the verify operation are directly stored
        /// in the SignatureStatus property of this class.</para>
        /// </remarks>
        /// <param name="bSignedData">The data that is to be verified.</param>
        /// <param name="pkpKey">The key that is to verify the signature</param>
        public void Verify(byte[] bSignedData, PublicKeyPacket pkpKey)
        {
            System.Security.Cryptography.HashAlgorithm haVerifyer;
            AsymmetricCipher acVerifyer;

            switch (this.HashAlgorithm)
            {
            case HashAlgorithms.MD5:
                haVerifyer = System.Security.Cryptography.MD5.Create();
                break;

            case HashAlgorithms.SHA1:
                haVerifyer = System.Security.Cryptography.SHA1.Create();
                break;

            default:
                throw(new System.Exception("Currently only MD5 and SHA1 are implemented as hash algorithms!"));
            }

            switch (this.SignatureAlgorithm)
            {
            case AsymAlgorithms.DSA:
                acVerifyer = new SharpPrivacy.SharpPrivacyLib.Cipher.DSA();
                break;

            case AsymAlgorithms.RSA_Encrypt_Sign:
            case AsymAlgorithms.RSA_Sign_Only:
                acVerifyer = new SharpPrivacy.SharpPrivacyLib.Cipher.RSA();
                break;

            default:
                throw(new System.Exception("Currently only DSA and RSA are implemented as signature algorithms!"));
            }

            byte[] bSignature = new byte[0];
            int    iCounter   = 0;

            if (this.Version <= SignaturePacketVersionNumbers.v3)
            {
                bSignature = new byte[5];

                bSignature[iCounter++] = (byte)this.SignatureType;
                long lTime = (dtTimeCreated.Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000;
                bSignature[iCounter++] = (byte)((lTime >> 24) & 0xFF);
                bSignature[iCounter++] = (byte)((lTime >> 16) & 0xFF);
                bSignature[iCounter++] = (byte)((lTime >> 8) & 0xFF);
                bSignature[iCounter++] = (byte)(lTime & 0xFF);
            }
            else
            {
                //Hashed Subpackets Length
                int lHashedSubPacketLength = 0;
                for (int i = 0; i < this.HashedSubPackets.Length; i++)
                {
                    lHashedSubPacketLength += this.HashedSubPackets[i].Generate().Length;
                }

                bSignature             = new byte[lHashedSubPacketLength + 12];
                bSignature[iCounter++] = 4;                 // Version
                bSignature[iCounter++] = (byte)this.SignatureType;
                bSignature[iCounter++] = (byte)this.SignatureAlgorithm;
                bSignature[iCounter++] = (byte)this.HashAlgorithm;

                //Hashed Subpackets
                bSignature[iCounter++] = (byte)((lHashedSubPacketLength >> 8) & 0xFF);
                bSignature[iCounter++] = (byte)(lHashedSubPacketLength & 0xFF);
                for (int i = 0; i < this.HashedSubPackets.Length; i++)
                {
                    byte[] bSubPacket = this.HashedSubPackets[i].Generate();
                    Array.Copy(bSubPacket, 0, bSignature, iCounter, bSubPacket.Length);
                    iCounter += bSubPacket.Length;
                }

                //Final Trailer of 6 bytes
                bSignature[iCounter++] = 0x04;
                bSignature[iCounter++] = 0xFF;
                bSignature[iCounter++] = (byte)(((lHashedSubPacketLength + 6) >> 24) & 0xFF);
                bSignature[iCounter++] = (byte)(((lHashedSubPacketLength + 6) >> 16) & 0xFF);
                bSignature[iCounter++] = (byte)(((lHashedSubPacketLength + 6) >> 8) & 0xFF);
                bSignature[iCounter++] = (byte)((lHashedSubPacketLength + 6) & 0xFF);
            }

            byte[] bData = new byte[bSignedData.Length + bSignature.Length];
            Array.Copy(bSignedData, bData, bSignedData.Length);
            Array.Copy(bSignature, 0, bData, bSignedData.Length, bSignature.Length);

            byte[]     bHash  = haVerifyer.ComputeHash(bData);
            BigInteger biHash = new BigInteger(bHash);

            //PKCS1 Encode the hash
            if (this.SignatureAlgorithm != AsymAlgorithms.DSA)
            {
                // We encode the MD in this way:
                //  0  A PAD(n bytes)   0  ASN(asnlen bytes)  MD(len bytes)
                // PAD consists of FF bytes.
                byte[] bASN = new byte[0];

                switch (this.HashAlgorithm)
                {
                case HashAlgorithms.MD5:
                    bASN = new byte[] { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08,
                                        0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
                                        0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
                    break;

                case HashAlgorithms.SHA1:
                    bASN = new byte[] { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
                                        0x2b, 0x0E, 0x03, 0x02, 0x1A, 0x05,
                                        0x00, 0x04, 0x14 };
                    break;
                }

                int    iFrameSize  = (pkpKey.KeyMaterial[0].bitCount() + 7) / 8;
                byte[] bFrame      = new byte[iFrameSize];
                int    iASNCounter = 0;

                bFrame[iASNCounter++] = 0;
                bFrame[iASNCounter++] = 1;
                int iFFLength = iFrameSize - bHash.Length - bASN.Length - 3;
                for (int i = 0; i < iFFLength; i++)
                {
                    bFrame[iASNCounter++] = 0xFF;
                }
                bFrame[iASNCounter++] = 0;
                Array.Copy(bASN, 0, bFrame, iASNCounter, bASN.Length);
                iASNCounter += bASN.Length;
                Array.Copy(bHash, 0, bFrame, iASNCounter, bHash.Length);
                biHash = new BigInteger(bFrame);
            }

            if (acVerifyer.Verify(this.Signature, biHash, pkpKey))
            {
                ssSignatureStatus = SignatureStatusTypes.Valid;
            }
            else
            {
                ssSignatureStatus = SignatureStatusTypes.Invalid;
            }
        }
コード例 #11
0
        /// <summary>
        /// Encryptes the session key stored in the SessionKey property
        /// and saves the results in the EncryptedSessionKey property.
        /// </summary>
        /// <remarks>This method also calles EncodeSessionKey so that it
        /// does not have been called before calling EncryptSessionKey.
        /// <p></p>
        /// Please note: calling this function takes some time, because
        /// asymmetrical encryption takes some time!
        /// </remarks>
        /// <param name="pkpPacket">An PublicKeyPacket to which
        /// the sessionkey should be encrypted to.</param>
        public void EncryptSessionKey(PublicKeyPacket pkpPacket)
        {
            EncodeSessionKey(pkpPacket.KeyMaterial[0].bitCount());

            AsymmetricCipher acCipher = new RSA();
            switch (aaPublicAlgorithm) {
                case AsymAlgorithms.ElGama_Encrypt_Sign:
                case AsymAlgorithms.ElGamal_Encrypt_Only:
                    acCipher = new ElGamal();
                    break;

                case AsymAlgorithms.RSA_Encrypt_Only:
                case AsymAlgorithms.RSA_Encrypt_Sign:
                    acCipher = new RSA();
                    break;

                default:
                    throw new System.Exception("The chosen public key algorithm is not yet implemented!");
            }

            this.bIsUpdated = true;
            biEncryptedSessionKey = acCipher.Encrypt(new BigInteger(this.bEncodedSessionKey), pkpPacket);
        }
コード例 #12
0
 public abstract bool Verify(BigInteger[] biSignature, BigInteger biHash, PublicKeyPacket pkpKey);
コード例 #13
0
 public abstract BigInteger[] Encrypt(BigInteger biPlain, PublicKeyPacket pkpKey);
コード例 #14
0
ファイル: RSA.cs プロジェクト: kabili207/SharpPrivacy
        /// <summary>
        /// Public key operation. Verifies biSignature with the keydata
        /// in the given public key packet and returns true if the signature
        /// is valid.
        /// </summary>
        /// <param name="biSignature">The signature that is about to
        /// be verified</param>
        /// <param name="biHash">The hash value of the signed message.</param>
        /// <param name="pkpKey">The public key packet with the key
        /// material for the verification.</param>
        /// <returns>True if the signature is valid, otherwise 
        /// false</returns>
        /// <remarks>No remarks</remarks>
        public override bool Verify(BigInteger[] biSignature, BigInteger biHash, PublicKeyPacket pkpKey)
        {
            RSA_Public_Key rpkKey = new RSA_Public_Key();

            if ((pkpKey.Algorithm != AsymAlgorithms.RSA_Encrypt_Sign) &&
                    (pkpKey.Algorithm != AsymAlgorithms.RSA_Sign_Only)) {
                throw new System.ArgumentException("This public key is not supposed to be used for RSA signatures.");
            }
            if (pkpKey.KeyMaterial.Length != 2) {
                throw new System.ArgumentException("This is not a valid RSA Key");
            }

            rpkKey.n = pkpKey.KeyMaterial[0];
            rpkKey.e = pkpKey.KeyMaterial[1];

            BigInteger biReturn = Encrypt(biSignature[0], rpkKey)[0];

            return biReturn == biHash;
        }
コード例 #15
0
        /// <summary>
        /// Generate a key pair
        /// </summary>
        /// <param name="iKeySize">Encription key size</param>
        /// <param name="strPassphrase">passhrase for the key pair</param>
        /// <param name="userID">primary user id</param>
        /// <param name="email">user email</param>
        /// <param name="notation">xml encoded user info</param>
        /// <param name="expirationTime">expiration date of the primary key (new DateTime(0) == never)</param>
        /// <param name="keyType">1: RSA/DSA   0:Elgamal/DSA(DEFAULT)</param>
        /// <param name="isRevocableKey">revocable?</param>
        /// <param name="isRevocableSubkey">revocable subkey?</param>
        public void GenerateKey(int iKeySize, string strPassphrase, string userID, string email, string notation, DateTime expirationTime, int keyType, bool isRevocableKey, bool isRevocableSubkey)
        {
            if(iKeySize % 1024 != 0)
                throw new Exception("Keysize must be a 1024 multiple");

            System.Security.Cryptography.RandomNumberGenerator rngRand;

            // let's first create the encryption key
            BigInteger[][] biEncryptionKey;
            if (keyType == 1) {
                // it's a RSA/DSA key
                biEncryptionKey = GenerateRSAEncryptionKey(iKeySize);
            } else {
                // it's an elgamal/DSA key DEFAULF
                biEncryptionKey = GenerateElGamalEncryptionKey(iKeySize);
            }

            // now the signature key
            BigInteger[][] biSignatureKey = GenerateDSASignatureKey();

            PublicKeyPacket pkpSignatureKey = new PublicKeyPacket(false);
            pkpSignatureKey.Algorithm = AsymAlgorithms.DSA;
            pkpSignatureKey.KeyMaterial = biSignatureKey[0];
            pkpSignatureKey.TimeCreated = DateTime.Now;
            pkpSignatureKey.Version = PublicKeyPacketVersionNumbers.v4;

            SecretKeyPacket skpSignatureKey = new SecretKeyPacket(false);
            skpSignatureKey.SymmetricalAlgorithm = SymAlgorithms.AES256;
            skpSignatureKey.PublicKey = pkpSignatureKey;
            skpSignatureKey.InitialVector = new byte[CipherHelper.CipherBlockSize(SymAlgorithms.AES256)];
            rngRand = System.Security.Cryptography.RandomNumberGenerator.Create();
            rngRand.GetBytes(skpSignatureKey.InitialVector);
            skpSignatureKey.EncryptKeyMaterial(biSignatureKey[1], strPassphrase);
            skpSignatureKey.PublicKey = pkpSignatureKey;

            PublicKeyPacket pkpEncryptionKey = new PublicKeyPacket(true);
            if (keyType == 0) {
                // it's an elgamal/DSA key
                pkpEncryptionKey.Algorithm = AsymAlgorithms.ElGamal_Encrypt_Only;
            } else if (keyType == 1) {
                // it's a RSA/DSA key
                pkpEncryptionKey.Algorithm = AsymAlgorithms.RSA_Encrypt_Only;
            }
            pkpEncryptionKey.KeyMaterial = biEncryptionKey[0];
            pkpEncryptionKey.TimeCreated = DateTime.Now;
            pkpEncryptionKey.Version = PublicKeyPacketVersionNumbers.v4;

            SecretKeyPacket skpEncryptionKey = new SecretKeyPacket(true);
            skpEncryptionKey.SymmetricalAlgorithm = SymAlgorithms.AES256;
            skpEncryptionKey.PublicKey = pkpEncryptionKey;
            skpEncryptionKey.InitialVector = new byte[CipherHelper.CipherBlockSize(SymAlgorithms.AES256)];
            rngRand = System.Security.Cryptography.RandomNumberGenerator.Create();
            rngRand.GetBytes(skpEncryptionKey.InitialVector);
            skpEncryptionKey.EncryptKeyMaterial(biEncryptionKey[1], strPassphrase);
            skpEncryptionKey.PublicKey = pkpEncryptionKey;

            CertifiedUserID cuiUID = new CertifiedUserID();
            UserIDPacket uipUID = new UserIDPacket();
            uipUID.UserID = userID.Trim() + " <" + email.Trim() + ">";
            cuiUID.UserID = uipUID;
            SignaturePacket spSelfSig = new SignaturePacket();
            if (notation != null) {
                SignatureSubPacket sspNotation = new SignatureSubPacket();
                sspNotation.Type = SignatureSubPacketTypes.NotationData;
                sspNotation.NotationName = "PersonalData";
                sspNotation.NotationValue = notation;
                spSelfSig.AddSubPacket(sspNotation,false);
            }
            if (expirationTime.Ticks != 0) {
                SignatureSubPacket sspExpiration = new SignatureSubPacket();
                sspExpiration.Type = SignatureSubPacketTypes.KeyExpirationTime;
                sspExpiration.KeyExpirationTime = new DateTime(expirationTime.Ticks + (new DateTime(1970,1,2)).Ticks - pkpEncryptionKey.TimeCreated.Ticks);
                spSelfSig.AddSubPacket(sspExpiration, true);
            }
            if (!isRevocableKey) {
                SignatureSubPacket sspRevocable = new SignatureSubPacket();
                sspRevocable.Type = SignatureSubPacketTypes.Revocable;
                sspRevocable.Revocable = isRevocableKey;
                spSelfSig.AddSubPacket(sspRevocable, true);
            }
            SignatureSubPacket sspPrimaryUID = new SignatureSubPacket();
            sspPrimaryUID.Type = SignatureSubPacketTypes.PrimaryUserID;
            sspPrimaryUID.Revocable = true;
            spSelfSig.AddSubPacket(sspPrimaryUID, true);

            spSelfSig.Version = SignaturePacketVersionNumbers.v4;
            spSelfSig.HashAlgorithm = HashAlgorithms.SHA1;
            spSelfSig.KeyID = pkpSignatureKey.KeyID;
            spSelfSig.TimeCreated = DateTime.Now;
            SignatureSubPacket sspPrimaryUserID = new SignatureSubPacket();
            sspPrimaryUserID.Type = SignatureSubPacketTypes.PrimaryUserID;
            sspPrimaryUserID.PrimaryUserID = true;
            spSelfSig.AddSubPacket(sspPrimaryUserID, true);
            SignatureSubPacket sspPreferedSymAlgos = new SignatureSubPacket();
            sspPreferedSymAlgos.Type = SignatureSubPacketTypes.PreferedSymmetricAlgorithms;
            sspPreferedSymAlgos.PreferedSymAlgos = new SymAlgorithms[] {SymAlgorithms.AES256, SymAlgorithms.AES192, SymAlgorithms.AES256, SymAlgorithms.CAST5, SymAlgorithms.Triple_DES};
            spSelfSig.AddSubPacket(sspPreferedSymAlgos, true);
            SignatureSubPacket sspPreferedHashAlgos = new SignatureSubPacket();
            sspPreferedHashAlgos.Type = SignatureSubPacketTypes.PreferedHashAlgorithms;
            sspPreferedHashAlgos.PreferedHashAlgos = new HashAlgorithms[] {HashAlgorithms.SHA1};
            spSelfSig.AddSubPacket(sspPreferedHashAlgos, true);

            cuiUID.Certificates = new System.Collections.ArrayList();
            cuiUID.Sign(spSelfSig, skpSignatureKey, strPassphrase, pkpSignatureKey);

            CertifiedPublicSubkey cpsEncryptionKey = new CertifiedPublicSubkey();
            cpsEncryptionKey.Subkey = pkpEncryptionKey;
            cpsEncryptionKey.SignKeyBindingSignature(pkpSignatureKey, skpSignatureKey, strPassphrase, expirationTime, isRevocableSubkey);

            TransportablePublicKey tpkPublicKey = new TransportablePublicKey();
            tpkPublicKey.PrimaryKey = pkpSignatureKey;
            tpkPublicKey.SubKeys.Add(cpsEncryptionKey);
            tpkPublicKey.Certifications.Add(cuiUID);

            this.PublicRing.AddPublicKey(tpkPublicKey);

            TransportableSecretKey tskSecretKey = new TransportableSecretKey();
            tskSecretKey.PrimaryKey = skpSignatureKey;
            tskSecretKey.SubKeys.Add(skpEncryptionKey);
            tskSecretKey.UserIDs.Add(uipUID);

            this.SecretRing.AddSecretKey(tskSecretKey);
        }
コード例 #16
0
        public void GenerateKey(string strName, string strEmail, string strKeyType, int iKeySize, long lExpiration, string strPassphrase)
        {
            if (strKeyType == "ElGamal/DSA") {
                System.Security.Cryptography.RandomNumberGenerator rngRand = System.Security.Cryptography.RandomNumberGenerator.Create();

                // let's first create the encryption key
                BigInteger[][] biEncryptionKey = GenerateEncryptionKey(iKeySize);

                // now the signature key
                BigInteger[][] biSignatureKey = GenerateSignatureKey();

                PublicKeyPacket pkpSignatureKey = new PublicKeyPacket(false);
                pkpSignatureKey.Algorithm = AsymAlgorithms.DSA;
                pkpSignatureKey.KeyMaterial = biSignatureKey[0];
                pkpSignatureKey.TimeCreated = DateTime.Now;
                pkpSignatureKey.Version = PublicKeyPacketVersionNumbers.v4;

                SecretKeyPacket skpSignatureKey = new SecretKeyPacket(false);
                skpSignatureKey.SymmetricalAlgorithm = SymAlgorithms.AES256;
                skpSignatureKey.PublicKey = pkpSignatureKey;
                skpSignatureKey.InitialVector = new byte[CipherHelper.CipherBlockSize(SymAlgorithms.AES256)];
                rngRand.GetBytes(skpSignatureKey.InitialVector);
                skpSignatureKey.EncryptKeyMaterial(biSignatureKey[1], strPassphrase);
                skpSignatureKey.PublicKey = pkpSignatureKey;

                PublicKeyPacket pkpEncryptionKey = new PublicKeyPacket(true);
                pkpEncryptionKey.Algorithm = AsymAlgorithms.ElGamal_Encrypt_Only;
                pkpEncryptionKey.KeyMaterial = biEncryptionKey[0];
                pkpEncryptionKey.TimeCreated = DateTime.Now;
                pkpEncryptionKey.Version = PublicKeyPacketVersionNumbers.v4;

                SecretKeyPacket skpEncryptionKey = new SecretKeyPacket(true);
                skpEncryptionKey.SymmetricalAlgorithm = SymAlgorithms.AES256;
                skpEncryptionKey.PublicKey = pkpEncryptionKey;
                skpEncryptionKey.InitialVector = new byte[CipherHelper.CipherBlockSize(SymAlgorithms.AES256)];
                rngRand.GetBytes(skpEncryptionKey.InitialVector);
                skpEncryptionKey.EncryptKeyMaterial(biEncryptionKey[1], strPassphrase);
                skpEncryptionKey.PublicKey = pkpEncryptionKey;

                CertifiedUserID cuiUID = new CertifiedUserID();
                UserIDPacket uipUID = new UserIDPacket();
                uipUID.UserID = strName.Trim() + " <" + strEmail.Trim() + ">";
                cuiUID.UserID = uipUID;
                SignaturePacket spSelfSig = new SignaturePacket();
                spSelfSig.Version = SignaturePacketVersionNumbers.v4;
                spSelfSig.HashAlgorithm = HashAlgorithms.SHA1;
                spSelfSig.KeyID = pkpSignatureKey.KeyID;
                spSelfSig.TimeCreated = DateTime.Now;
                SignatureSubPacket sspPrimaryUserID = new SignatureSubPacket();
                sspPrimaryUserID.Type = SignatureSubPacketTypes.PrimaryUserID;
                sspPrimaryUserID.PrimaryUserID = true;
                spSelfSig.AddSubPacket(sspPrimaryUserID, true);
                SignatureSubPacket sspPreferedSymAlgos = new SignatureSubPacket();
                sspPreferedSymAlgos.Type = SignatureSubPacketTypes.PreferedSymmetricAlgorithms;
                sspPreferedSymAlgos.PreferedSymAlgos = new SymAlgorithms[] {SymAlgorithms.AES256, SymAlgorithms.AES192, SymAlgorithms.AES256, SymAlgorithms.CAST5, SymAlgorithms.Triple_DES};
                spSelfSig.AddSubPacket(sspPreferedSymAlgos, true);
                SignatureSubPacket sspPreferedHashAlgos = new SignatureSubPacket();
                sspPreferedHashAlgos.Type = SignatureSubPacketTypes.PreferedHashAlgorithms;
                sspPreferedHashAlgos.PreferedHashAlgos = new HashAlgorithms[] {HashAlgorithms.SHA1};
                spSelfSig.AddSubPacket(sspPreferedHashAlgos, true);
                if (lExpiration != 0) {
                    SignatureSubPacket sspExpiration = new SignatureSubPacket();
                    sspExpiration.Type = SignatureSubPacketTypes.SignatureExpirationTime;
                    sspExpiration.SignatureExpirationTime = new DateTime(lExpiration);
                    spSelfSig.AddSubPacket(sspExpiration, true);
                }
                cuiUID.Certificates = new System.Collections.ArrayList();
                cuiUID.Sign(spSelfSig, skpSignatureKey, strPassphrase, pkpSignatureKey);

                CertifiedPublicSubkey cpsEncryptionKey = new CertifiedPublicSubkey();
                cpsEncryptionKey.Subkey = pkpEncryptionKey;
                cpsEncryptionKey.SignKeyBindingSignature(pkpSignatureKey, skpSignatureKey, strPassphrase, new DateTime(lExpiration), true);

                TransportablePublicKey tpkPublicKey = new TransportablePublicKey();
                tpkPublicKey.PrimaryKey = pkpSignatureKey;
                tpkPublicKey.SubKeys.Add(cpsEncryptionKey);
                tpkPublicKey.Certifications.Add(cuiUID);

                TransportableSecretKey tskSecretKey = new TransportableSecretKey();
                tskSecretKey.PrimaryKey = skpSignatureKey;
                tskSecretKey.SubKeys.Add(skpEncryptionKey);
                tskSecretKey.UserIDs.Add(uipUID);

                this.pkrKeyRing.AddPublicKey(tpkPublicKey);
                this.skrKeyRing.AddSecretKey(tskSecretKey);
                pkrKeyRing.Save();
                skrKeyRing.Save();

            // it's an RSA key
            } else if (strKeyType == "RSA") {

            }
        }
コード例 #17
0
        /// <summary>
        /// Generates a subkey for the specified primary key pair
        /// </summary>
        /// <param name="iKeySize">size of the subkey</param>
        /// <param name="strPassphrase">passphrase for the primar secret key</param>
        /// <param name="PrimaryKeyID">primary key pair keyID</param>
        /// <param name="expirationTime">expiration time for the subkey (new DateTime(0) == never)</param>
        /// <param name="isRevocableSubkey">is revocable?</param>
        public void GenerateSubkey(int iKeySize, string strPassphrase, ulong PrimaryKeyID, DateTime expirationTime, bool isRevocableSubkey)
        {
            if (iKeySize % 1024 != 0)
                throw new Exception("Keysize must be a 1024 multiple");
            TransportablePublicKey tpkKey = this.PublicRing.Find(PrimaryKeyID,false);
            TransportableSecretKey tskKey = this.SecretRing.Find(PrimaryKeyID);
            System.Security.Cryptography.RandomNumberGenerator rngRand;

            BigInteger[][] biEncryptionKey = GenerateElGamalEncryptionKey(iKeySize);

            PublicKeyPacket pkpEncryptionKey = new PublicKeyPacket(true);
            pkpEncryptionKey.Algorithm = AsymAlgorithms.ElGamal_Encrypt_Only;
            pkpEncryptionKey.KeyMaterial = biEncryptionKey[0];
            pkpEncryptionKey.TimeCreated = DateTime.Now;
            pkpEncryptionKey.Version = PublicKeyPacketVersionNumbers.v4;

            SecretKeyPacket skpEncryptionKey = new SecretKeyPacket(true);
            skpEncryptionKey.SymmetricalAlgorithm = SymAlgorithms.AES256;
            skpEncryptionKey.PublicKey = pkpEncryptionKey;
            skpEncryptionKey.InitialVector = new byte[CipherHelper.CipherBlockSize(SymAlgorithms.AES256)];
            rngRand = System.Security.Cryptography.RandomNumberGenerator.Create();
            rngRand.GetBytes(skpEncryptionKey.InitialVector);
            skpEncryptionKey.EncryptKeyMaterial(biEncryptionKey[1], strPassphrase);
            skpEncryptionKey.PublicKey = pkpEncryptionKey;

            CertifiedPublicSubkey cpsEncryptionKey = new CertifiedPublicSubkey();
            cpsEncryptionKey.Subkey = pkpEncryptionKey;
            cpsEncryptionKey.SignKeyBindingSignature(tpkKey.PrimaryKey, tskKey.PrimaryKey, strPassphrase, expirationTime, isRevocableSubkey);

            tpkKey.SubKeys.Add(cpsEncryptionKey);
            this.PublicRing.AddPublicKey(tpkKey);

            tskKey.SubKeys.Add(skpEncryptionKey);
            this.SecretRing.AddSecretKey(tskKey);
        }
コード例 #18
0
ファイル: ElGamal.cs プロジェクト: kabili207/SharpPrivacy
        /// <summary>
        /// Public key operation. Encrypts biInput with the keydata
        /// in the given public key packet.
        /// </summary>
        /// <param name="biInput">The plaintext that is about to
        /// be encrypted</param>
        /// <param name="pkpKey">The public key packet with the key
        /// material for the encryption</param>
        /// <returns>The encrypted ciphertext.</returns>
        /// <remarks>No remarks.</remarks>
        public override BigInteger[] Encrypt(BigInteger biInput, PublicKeyPacket pkpKey)
        {
            EG_Public_Key epkKey = new EG_Public_Key();
            epkKey.p = pkpKey.KeyMaterial[0];
            epkKey.g = pkpKey.KeyMaterial[1];
            epkKey.y = pkpKey.KeyMaterial[2];

            BigInteger k = new BigInteger();

            //Random number needed for encryption
            k = BigInteger.genRandom(epkKey.p.bitCount()-1);

            while (k > (epkKey.p-1)) {
                k = new BigInteger();
                k = BigInteger.genRandom(epkKey.p.bitCount()-1);
            }

            BigInteger B = epkKey.g.modPow(k, epkKey.p);
            BigInteger c = epkKey.y.modPow(k, epkKey.p);
            c = (biInput * c) % epkKey.p;
            //BigInteger c = (biInput * epkKey.y.modPow(k, epkKey.p)) % epkKey.p;

            BigInteger[] biOutput = new BigInteger[2];

            biOutput[0] = B;
            biOutput[1] = c;

            return biOutput;
        }
コード例 #19
0
        /// <summary>
        /// Parses the packet given as byte array into the current
        /// class and returns this with the populated parameters.
        /// </summary>
        /// <param name="bData">A byte array containing an OpenPGP
        /// representation of the packet.</param>
        /// <returns>Returns an SecretKeyPacket that containes
        /// the parsed properties.</returns>
        /// <remarks>No remarks</remarks>
        public override Packet ParsePacket(byte[] bData)
        {
            PublicKey = new PublicKeyPacket();
            PublicKey = (PublicKeyPacket)PublicKey.ParsePacket(bData);

            int iPos = this.PublicKey.Length;

            if (bData[iPos] == 255)
            {
                this.bIsEncrypted = true;
                iPos++;

                saSymmetricalAlgorithm = (SymAlgorithms)bData[iPos++];

                //String2Key Specifier expected
                // a S2K specifier is at max 11 bytes long
                byte[] bS2k = new byte[11];
                Array.Copy(bData, iPos, bS2k, 0, bS2k.Length);
                this.S2KSpecifier.ParseSpecifier(bS2k);
                iPos += S2KSpecifier.CraftContent().Length;

                //Parse Initial Vector
                int iBlockSize = CipherHelper.CipherBlockSize(saSymmetricalAlgorithm);
                this.InitialVector = new byte[iBlockSize];
                Array.Copy(bData, iPos, bInitialVector, 0, iBlockSize);
                iPos += iBlockSize;

                //Parse Encrypted MPIs (including checksum!!!)
                this.bEncryptedKeyMaterial = new byte[bData.Length - iPos];
                Array.Copy(bData, iPos, bEncryptedKeyMaterial, 0, bData.Length - iPos);
            }
            else if (bData[iPos] == 0)
            {
                this.bIsEncrypted = false;
                iPos++;

                //Parse unencrypted MPIs
                byte[] bMPIs = new byte[bData.Length - iPos - 2];
                Array.Copy(bData, iPos, bMPIs, 0, bMPIs.Length);

                biDecryptedKeyMaterial = BigInteger.ParseMPIs(bMPIs);

                iPos           += bMPIs.Length;
                this.sChecksum  = (ushort)(bData[iPos++] << 8);
                this.sChecksum ^= (ushort)bData[iPos];

                //validate checksum
                int iCurrentChecksum = 0;
                for (int i = 0; i < bMPIs.Length; i++)
                {
                    iCurrentChecksum = (iCurrentChecksum + bMPIs[i]) % 65536;
                }

                if (iCurrentChecksum != sChecksum)
                {
                    throw(new Exception("Key checksum is not correct. Someone played with the key?!"));
                }
            }
            else
            {
                //Encrypted in some strange way. We're not going
                //to support this
                throw(new Exception("This secret key is encrypted in some strange way. Sorry, but we're not going to support this. Get a real key!"));
            }


            this.bIsUpdated = false;
            return(this);
        }
コード例 #20
0
        /// <summary>
        /// Parses the packet given as byte array into the current
        /// class and returns this with the populated parameters.
        /// </summary>
        /// <param name="bData">A byte array containing an OpenPGP
        /// representation of the packet.</param>
        /// <returns>Returns an SecretKeyPacket that containes
        /// the parsed properties.</returns>
        /// <remarks>No remarks</remarks>
        public override Packet ParsePacket(byte[] bData)
        {
            PublicKey = new PublicKeyPacket();
            PublicKey = (PublicKeyPacket)PublicKey.ParsePacket(bData);

            int iPos = this.PublicKey.Length;

            if (bData[iPos] == 255) {
                this.bIsEncrypted = true;
                iPos++;

                saSymmetricalAlgorithm = (SymAlgorithms)bData[iPos++];

                //String2Key Specifier expected
                // a S2K specifier is at max 11 bytes long
                byte[] bS2k = new byte[11];
                Array.Copy(bData, iPos, bS2k, 0, bS2k.Length);
                this.S2KSpecifier.ParseSpecifier(bS2k);
                iPos += S2KSpecifier.CraftContent().Length;

                //Parse Initial Vector
                int iBlockSize = CipherHelper.CipherBlockSize(saSymmetricalAlgorithm);
                this.InitialVector = new byte[iBlockSize];
                Array.Copy(bData, iPos, bInitialVector, 0, iBlockSize);
                iPos += iBlockSize;

                //Parse Encrypted MPIs (including checksum!!!)
                this.bEncryptedKeyMaterial = new byte[bData.Length - iPos];
                Array.Copy(bData, iPos, bEncryptedKeyMaterial, 0, bData.Length - iPos);
            } else if (bData[iPos] == 0) {
                this.bIsEncrypted = false;
                iPos++;

                //Parse unencrypted MPIs
                byte[] bMPIs = new byte[bData.Length - iPos - 2];
                Array.Copy(bData, iPos, bMPIs, 0, bMPIs.Length);

                biDecryptedKeyMaterial = BigInteger.ParseMPIs(bMPIs);

                iPos += bMPIs.Length;
                this.sChecksum = (ushort)(bData[iPos++] << 8);
                this.sChecksum ^= (ushort)bData[iPos];

                //validate checksum
                int iCurrentChecksum = 0;
                for (int i=0; i<bMPIs.Length; i++)
                    iCurrentChecksum = (iCurrentChecksum + bMPIs[i]) % 65536;

                if (iCurrentChecksum != sChecksum)
                    throw(new Exception("Key checksum is not correct. Someone played with the key?!"));

            } else {
                //Encrypted in some strange way. We're not going
                //to support this
                throw(new Exception("This secret key is encrypted in some strange way. Sorry, but we're not going to support this. Get a real key!"));
            }

            this.bIsUpdated = false;
            return this;
        }