示例#1
0
        public override void Serialize(Stream aStream, object aObject)
        {
            /* check for required parameters */
            if (aStream == null)
            {
                throw new ArgumentNullException("aStream");
            }

            if (aObject == null)
            {
                throw new ArgumentNullException("aObject");
            }

            PasswordFinder pwFinder = null;

            if (GetPassphraseCallbackMethod != null)
            {
                pwFinder = new PasswordFinder(GetPassphraseCallbackMethod);
            }
            PinnedArray <char> passphrase = null;

            if (pwFinder != null)
            {
                passphrase      = new PinnedArray <char>(0);
                passphrase.Data = pwFinder.GetPassword();
            }

            byte cipherType;

            if (passphrase == null || passphrase.Data.Length == 0)
            {
                cipherType = SSH_CIPHER_NONE;
            }
            else
            {
                cipherType = SSH_CIPHER_3DES;
            }

            BlobBuilder builder = new BlobBuilder();

            ISshKey          sshKey          = aObject as ISshKey;
            RsaKeyParameters publicKeyParams = sshKey.GetPublicKeyParameters()
                                               as RsaKeyParameters;
            RsaPrivateCrtKeyParameters privateKeyParams = sshKey.GetPrivateKeyParameters()
                                                          as RsaPrivateCrtKeyParameters;

            /* writing info headers */
            builder.AddBytes(Encoding.ASCII.GetBytes(FILE_HEADER_LINE + "\n"));
            builder.AddUInt8(0);          //end of string
            builder.AddUInt8(cipherType); //cipher
            builder.AddInt(0);            //reserved

            /* writing public key */
            builder.AddInt(sshKey.Size);
            builder.AddSsh1BigIntBlob(publicKeyParams.Modulus);
            builder.AddSsh1BigIntBlob(publicKeyParams.Exponent);
            builder.AddStringBlob(sshKey.Comment);

            /* writing private key */
            BlobBuilder privateKeyBuilder = new BlobBuilder();

            /* adding some control values */
            Random random = new Random();

            byte[] resultCheck = new byte[2];
            random.NextBytes(resultCheck);

            privateKeyBuilder.AddUInt8(resultCheck[0]);
            privateKeyBuilder.AddUInt8(resultCheck[1]);
            privateKeyBuilder.AddUInt8(resultCheck[0]);
            privateKeyBuilder.AddUInt8(resultCheck[1]);
            privateKeyBuilder.AddSsh1BigIntBlob(privateKeyParams.Exponent);
            privateKeyBuilder.AddSsh1BigIntBlob(privateKeyParams.DQ);
            privateKeyBuilder.AddSsh1BigIntBlob(privateKeyParams.P);
            privateKeyBuilder.AddSsh1BigIntBlob(privateKeyParams.Q);

            if (cipherType == SSH_CIPHER_NONE)
            {
                /* plain-text */
                builder.AddBytes(privateKeyBuilder.GetBlobAsPinnedByteArray().Data);
            }
            else
            {
                byte[] keydata;
                using (MD5 md5 = MD5.Create()) {
                    keydata = md5.ComputeHash(Encoding.ASCII.GetBytes(passphrase.Data));
                }

                /* encryption */
                DesSsh1Engine desEngine = new DesSsh1Engine();
                desEngine.Init(true, new KeyParameter(keydata));

                BufferedBlockCipher bufferedBlockCipher = new BufferedBlockCipher(desEngine);
                byte[] ouputBuffer = bufferedBlockCipher.ProcessBytes(
                    privateKeyBuilder.GetBlobAsPinnedByteArray().Data);

                builder.AddBytes(ouputBuffer);

                passphrase.Dispose();
            }

            /* writing result to file */
            var builderOutput = builder.GetBlobAsPinnedByteArray();

            aStream.Write(builderOutput.Data, 0, builderOutput.Data.Length);
            aStream.Close();
        }