Hey guys!
Some time ago, I saw someone asking about trial software protection, and my first thought was a '30-day evaluation' mode.

I was thinking on how it can be done without using any third-party programs.

How can I detect the first run and count down (or up) the number of remaining days? And how can I securely store it on the user's computer?

I know that this might be the easiest method to crack, but it is a nice way to learn :)

Thanks!

Recommended Answers

All 17 Replies

does ur application uses Sql Database???????

I don't even have a application. I'll just ty it out.
And SQL databases can be edited. :)

I've just built a small program with a security element to it that recognises your first logon and prompts you to change your password straight away. But if it isn;t your first logon, then it will just wait for your password.

I do this by creating keys in the System Registry. People who are very savvy with computers might work it out (eventually), but if you bury it deep enough in a directory structure that looks like it has nothing to do with your program, you might get away with it.

then all you'd have to do is build some conditions to say if the reg key doesn't exist, create it with a value of 30, however, if it does exist, then check system date against last run date (this can be another reg key) and depending on how they compare, subtract one from the reg key.

But that's just my opinion. I'm sure there's probably a better way.

Regards,

Rob.

I first thought on something more internal, like a dll that stores everything, but I didn't figured out on how to update the dll with the start date and all.

Also, I thought on a simply settings file, but that would be too easy.

There is some way to encrypt a string and decrypt it at the runtime? encrypting the string would make difficult to understand, so it can be more easily stored into registry.

I've just finished developing an encoder/decoder. It's a very roundabout way of doing it, but I have a whole bunch of textboxes, lets say for the sake of this example, 26 of them.

The contents start with 01A, then go to 02B, 03C and so on all the way up to 26Z. This is in a groupbox called grpFixed

Then I have another set of Textboxes in grpDynamic. Dynamic can be a preset randomized alphabet of your choice that stays fixed, or you can be adventurous like me and start building in a cycling system that constantly rotates the dynamic alphabet after each character making it even more difficult to decipher.

Anyway, the dynamic boxes might start with 01Q and then go onto 02D, 03V and finish on 26T. Then use a 'For Each to step through your string, find the first letter in the fixed alphabet and then bring back the corresponding number from the dynamic group.

So using my above example, a passkey of "ABC" would then produce an encrypted string that looks like "QDV"

To decode you just do the exact same thing but in reverse. Loading the retreived passkey through the dynamic alphabet so that Q recognises it is 01 and then it steps through the fixed alphabet, find 01 and then returns an A in its place.

Clear as mud?

Rob.

Not so clear, I thought on using an encryption algorithm.

I got you idea, but it seems more easy to use algorithms, since they're ready. I've searched for it before, but didn't get it. I just need to encrypt the string, store it, and when the app runs, decrypt it. The key of encryption/decryption would be a pre-defined variable on the app.

Here's a snippet of the code I wrote to do what I described in my previous post. Apologies if it is terribly messy or badly written, but I'm still quite new to all of this and sort of am finding my own way of trying to do things.

Also, I've chopped a load of stuff out of it that had no bearing on the encode and decode process. I don't think I've taken anything important out but if you have problems with it, just shout.

Also this is the Encode only section but once you get this bit nailed, decoding is dead easy to work out.

Sub Encode()

For Each FixedTBox In Me.grpFixedAlpha.Controls
     If TypeOf FixedTBox Is TextBox Then
          Dim EncodeLetter As String
          EncodeLetter = Mid(txtInput.Text, txtSelectChar.Text, 1)
          If EncodeLetter = "" Then
               Msgbox = "Your message has been Encoded."
               Exit Sub
          Else
               If Mid(FixedTBox.text, 3, 1) = EncodeLetter Then
                    Dim TBoxRef
                    TBoxRef = Mid(FixedTBox.Text, 1, 2)
                    For Each DynamicTBox In Me.grpDynamicAlpha.Controls
                         If TypeOf DynamicTBox Is TextBox Then
                              If TBoxRef = Mid(DynamicTBox.Text, 1, 2) Then
                                   Dim Output As String
                                   Output = txtOutput.Text
                                   txtOutput.Text = Output & Mid(DynamicTBox.text, 3, 1)
                              End If
                         End If
                    Next DynamicTBox
               End If
          End If
     End If
Next FixedTBox

End Sub

Regards,

Rob.

Not so clear, I thought on using an encryption algorithm.

I got you idea, but it seems more easy to use algorithms, since they're ready. I've searched for it before, but didn't get it. I just need to encrypt the string, store it, and when the app runs, decrypt it. The key of encryption/decryption would be a pre-defined variable on the app.

Yikes... I'm not quite there yet... Though if you do work them out, I'd be interested to hear how it's done. If there's a way to do it more efficiently then I'm always open to suggestion.

I haven't saw your code when I answered, sorry!

I'll look at it, see if I can really get how it works.

Thank you!

I tried your code, but I didn't get how it works.

Can you explain it a little ... ?

Also, I've searched for encryption algorithms, and they all seems too hard to use.

I'll try to explain as clearly as possible.

Make two group boxes. One is grpFixedAlpha, the other is grpDynamicAlpha. In each one, put the number of textboxes you will want to use. So put 26 in each if you want A through Z, put 36 of you want A through Z AND 0 through 9.

For all the textboxes in grpFixedAlpha, enter the letters of the alphabet in the correct order and prefix each one with the logical number.

So the first textbox will contain "01A". In the next one "02B", in the next "03C", in the next "04D" and so on until "26Z" and if you're doing numbers as well then you'll have "270", "281", "292" all the way up to "369".

Then in the textboxes for the scrambled/dynamic alphabet, the textbox contents will still begin with 01,02,03etc but the letter that it contain will be different.

So the contents of the first textbox could be "01Q", the next could be "02D", the next 03V and so on until all of the characters you've put in your standard fixed alphabet have been used somewhere in this one.

So the numbers are in the same order, but the letters are all mixed up. So if you put one set of boxes above the other (presuming they were all in a single line) Where you had A, below it would be a Q, where the box was B; below it would be a D.

'Step through the standard alphabet one box at a time
     For Each FixedTBox In Me.grpFixedAlpha.Controls
          If TypeOf FixedTBox Is TextBox Then
'EncodeLetter is the character I need to encode. I look at the contents of a textbox, and then tell it to bring back a character determined by a mid. The mid should return txtSelectChar.text which is an incrementing number that begins at 1 and the mid must only ever dim one letter at a time.
               Dim EncodeLetter As String
               EncodeLetter = Mid(txtInput.Text, txtSelectChar.Text, 1)
               If EncodeLetter = "" Then
'If the encode letter is blank then there is no more text to encode (having rwached the end of the message or password) and the job must be complete, otherwise, we'll skip past this and do the job instead.
                    MsgBox = "Your message has been Encoded."
                    Exit Sub
               Else
'Here, I compare the last character of each Alphabet textbox with the Dim'ed letter I'm looking for.
                    If Mid(FixedTBox.text, 3, 1) = EncodeLetter Then
'If the letter I was looking for was an "A", then it would look at the box containing "01A", recognise that the third char is an "A" and then Dim the preceeding number. In this case "01".
                         Dim TBoxRef
                         TBoxRef = Mid(FixedTBox.Text, 1, 2)
'Now that we have the Number "01" held in memory, we need to find the scrambled/dynamic equivalent. So now we step through the dynamic alphabet and look for a textbox that contains "01".
                         For Each DynamicTBox In Me.grpDynamicAlpha.Controls
                              If TypeOf DynamicTBox Is TextBox Then
                                   If TBoxRef = Mid(DynamicTBox.Text, 1, 2) Then
'Aha. We've found a textbox that contains "01" at the start of it. So now, look to your output textbox, dim it's contents so you don't lose what's already there (if something was there to begin with) and then write in the letter that comes after the "01" we've just found in the scrambled/dynamic alphabet.
                                        Dim Output As String
                                        Output = txtOutput.Text
                                        txtOutput.Text = Output & Mid(DynamicTBox.text, 3, 1)
'I've just realised I didn't include this next line before. It's important that you tell the selected character value to increment by one so that the mid can look at the next letter in your word/message. 
                                        txtSelectChar.Text = txtSelectChar.Text + 1
                                   End If
                              End If
                         Next DynamicTBox
                    End If
               End If
          End If
     Next FixedTBox

I hope that helps to clear it up a bit. If I'm still not being very clear, don't depsair, just let me know and I'll see if I can have another crack at explaining it or maybe even nail a basic project together and send it to you so you can see a working example.

Good luck,

Rob.

I had a bit of time to kill so I built a little sample project anyway. Even if you were able to work it out, there's a chance it'll still be useful to someone else.

The attachment contains a tiny little sample project that has just 1 form with 1 button. All you have to do is type in a password and hit Encode and it will do its mojo.

At least with this, you can F8 through it to see exactly what it's doing and where.

Hope it helps,

Rob.

an encrypted registry key is an easy way to do it. However, it's not foolproof.

Also, .NET already contains everything you need to do encryption.

Here's something simple:

First, add a class to handle encryption/decryption.
Second, import the following

Imports System
Imports System.Data
Imports System.Security
Imports System.Security.Cryptography
Imports System.Text
Imports System.IO

Then fill the class with this

Private Shared Entropy As Byte() = Encoding.Unicode.GetBytes("Put entropy characters here")

    Public Shared Function EncryptString(ByVal input As SecureString) As String

        Dim EncryptedData As Byte()
        EncryptedData = ProtectedData.Protect(Encoding.Unicode.GetBytes(ToUnsecureString(input)), Entropy, DataProtectionScope.LocalMachine)
        Return Convert.ToBase64String(EncryptedData)
    End Function

    Public Shared Function DecryptString(ByVal EncryptedData As String) As SecureString
        Dim DecryptedData As Byte()
        If EncryptedData.Length = 0 Then Return ToSecureString("")
        DecryptedData = ProtectedData.Unprotect(Convert.FromBase64String(EncryptedData), Entropy, DataProtectionScope.LocalMachine)
        Return ToSecureString(Encoding.Unicode.GetString(DecryptedData))
    End Function

    Public Shared Function ToSecureString(ByVal input As String) As SecureString
        Dim Secure As New SecureString
        For Each c As Char In input
            Secure.AppendChar(c)
        Next
        Secure.MakeReadOnly()
        Return Secure
    End Function

    Public Shared Function ToUnsecureString(ByVal input As SecureString) As String
        Dim Unsecure As String = String.Empty
        Dim ptr As IntPtr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(input)
        Try
            Unsecure = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(ptr)
        Finally
            System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(ptr)
        End Try
        Return Unsecure
    End Function

That will give you something simple for encryption/decryption and uses secure strings so that the data is even encrypted in memory, though you don't necessarily have to go that far.

This is machine level encryption to so it can only be decrypted on the same machine that encrypted it.

I've looked both codes and none seems clear to me, because both use commands that I'm not used to.

CodeWord, you code says that ProtectedData and DataProtectionScope are unavaliable, because they might not be declared or inacessible.

get connected, your code seems to do a nice work, in a simple way, but I'll search a bit more about the Mid command.

Thank you guys!

You need to reference the appropriate .NET assemblies.
Make sure you add a reference to System.Security

I've added the reference, seems ok now.

The only matter is that now it keep asking for a secure string to call the function, but I want to try it using a textbox. How can I convert the textbox contents to secure string? :o

the code I provided has functions to convert strings to securestrings and back.

You could do something like this:

Dim eString as string
eString = EncryptString(ToSecureString(textbox1.text))

The ToSecureString is a function in the same class as EncryptString.


had a typo with the textbox property. :P

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.