Page 1 of 1

RTF Question

Posted: Mon Nov 06, 2006 1:07 pm
by parad0x
Hi,

I am using the RichViewEdit Component and I need to be able to Encrypt Rich Text Format so that it keeps the formatting after it has been Decrypted.

I was at first just using the normal TRichEdit, but this is way to limited for what I need to do.

TRichViewEdit is amazing but I am having real frustrating problems trying to get my head around this!

I think to be able to encrypt the text and keep rtf formatting I first should encode it in Base64, I have DIMime units. I have been trying to encode it like this:

-----------------------------------

Code: Select all

procedure TForm1.Button1Click(Sender: TObject);
var
MSource,MDest: TMemoryStream;
begin
MSource := TMemoryStream.Create;
MDest := TMemoryStream.Create;
MSource.Position := 0;
MDest.Position := 0;
rve.SaveRTFToStream(MSource,False);
MDest.Position := 0;
MSource.Position := 0;
MimeEncodeStream(MSource,MDest);
MSource.Position := 0;
MDest.Position := 0;
rve.Clear;
rve.LoadRTFFromStream(MDest);
rve.Format;
MSource.Free;
MDest.Free;
end;
-----------------------------------

Example: the word 'test' is output like this:

Image

Is this the right way to be doing this?

Could somebody give me some hints on how I can achieve what I am trying to do?

Any hints or a pointer would be very well appreciated, I can encrypt the text no problem it's just knowing how to do it so it keeps the rtf formatting.

Many thanks

Chris

Posted: Mon Nov 06, 2006 4:04 pm
by Sergey Tkachenko
You encrypt RTF file in base64, and you can see base64-encoded text in the output.
To view the original document, you need to decode stream (MimeDecodeStream)

In your example, base64-encoded document is passed to LoadRVFFromStream. It's wrong, but in your case LoadRVFFromStream loads it as a plain text.

Posted: Tue Nov 07, 2006 8:14 pm
by parad0x
Hello Sergey,

Thank You for replying. I have just tried an experiment using FileStreams instead of MemoryStreams and RichViewEdit keeps the formatting once it's been Decrypted just fine.

I realise that this is now not related to your component, but I know you are a good programmer! Do you have any suggestions on what I could possibly do to Encrypt/Decrypt using TMemory Streams but also keep the formatting (.rtf) in TRichViewEdit?

Many thanks for your time

Chris

Posted: Tue Nov 07, 2006 9:16 pm
by Sergey Tkachenko
I do not understand why the results are different in TFileStream and TMemoryStream. It should not happen.

Posted: Wed Nov 08, 2006 7:15 pm
by parad0x
Hi,

I made a Unit for the TFileStreams - Encrypt / Decrypt routines:

Encrypt

Code: Select all

procedure TCrypto.Encrypt(Stream: TStream; OutFile: TStream); 
Var
  Dest : TMemoryStream;
begin
  try
    Stream.Seek(0,soFromBeginning);
    Dest := TMemoryStream.Create(OutFile);
    Cipher.InitStr(Password,TDCP_sha512);  // initialize the cipher with a hash of the passphrase
    Cipher.EncryptStream(Stream,Dest,Stream.Size); // encrypt the contents of the file
    Stream.Seek(0,soFromBeginning);
    Cipher.Burn;
    Dest.Free;
  except
    Raise CryptoException.CreateFmt('Cannot create file ''%s''.',[OutFile] );
  end;
end;
Decrypt

Code: Select all

procedure TCrypto.Decrypt(Stream: TStream; InFile: String); 
Var
  Source : TFileStream;
begin
  try
    Source := TFileStream.Create(InFile,fmOpenRead);
    Source.Seek(0,soFromBeginning);
    Cipher.InitStr(Password,TDCP_sha512);              // initialize the cipher with a hash of the passphrase
    Cipher.DecryptStream(Source,Stream,Source.Size); // encrypt the contents of the file
    Stream.Seek(0,soFromBeginning);
    Cipher.Burn;
    Source.Free;
  except
    Raise CryptoException.CreateFmt('File ''%s'' not opened.',[InFile] );
  end;
end;
I then use it like this:

Encrypt

Code: Select all

procedure TForm1.Save1Click(Sender: TObject);
Var 
  Stream : TMemoryStream; 
begin
if SaveDialog1.Execute then 
  Stream := TMemoryStream.Create;
  rve.SaveRTFToStream(stream,False);
Crypto.Password := '32AFDDDF603850AB04DCD4394B83B44773885E2D9642585F0012AD95A0FC20BEBC650B4067E061F2CE8A4AE4BA224300CEF92D0467B153A9FBB4C94E2BCEC9D4';
  Crypto.Encrypt(Stream,SaveDialog1.FileName);
  Stream.Free;
end;
Decrypt

Code: Select all

procedure TForm1.Open1Click(Sender: TObject);
Var 
  Stream : TMemoryStream; 
begin 
  If OpenDialog1.Execute then
    Begin 
      Stream := TMemoryStream.Create;
Crypto.Password := '32AFDDDF603850AB04DCD4394B83B44773885E2D9642585F0012AD95A0FC20BEBC650B4067E061F2CE8A4AE4BA224300CEF92D0467B153A9FBB4C94E2BCEC9D4';
Crypto.Decrypt(Stream,OpenDialog1.FileName);
rve.clear;
rve.LoadRTFFromStream(stream);
Stream.Free;
rve.Format;
end;
end;
This all works fine with RichViewEdit and keeps the formatting once it's been Decrypted, all images, Rich Text and everything is restored.

If I try this with TMemoryStreams, I just get rtf code back:

Code: Select all

{\rtf1\ansi\ansicpg0\uc1\deff0\deflang0\deflangfe0
I haven't posted all of the RTF code above, just a very small snippet because it's too big. I could post it if you like.

This is really confusing as to why I just can't Decrypt it back and keep (.rtf) formatting using TMemoryStreams.

I need to use TMemoryStreams because I would like to send the Encrypted Text through an email but then at the receiving end it needs to be Copied and Pasted back and then Decrypted. FileStreams are no good because it saves the encrypted content to a File, this would not be good for my program.

Do you know why this is happening? I have been trying to get this to work for a few months now! I am not a Professional Coder and learn as I go along.

Many thanks, and again thank you for your time

Chris