| Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date | |
| All threads index page 1 | |
We aren't looking for -perfect- security. It's not OpenSource: users have
no access to the source-code. The encryption key would be in the
source-code, probably separated into substrings scattered around so it's
not trivial to find it by looking at the executable (which is all the
end-user will have). Yes, a determined person could decompile the app,
trace through it to see how we build the key from the substrings, and find
those substrings. But that's not what we're worried about; the benefits
of gaining access to the data (or to send bad data to the server) don't
justify them expending even one-percent of that effort to get it. :) We
just don't want someone to see the Password lying unencrypted in the
settings file. Base64 is too easy to unencode because it doesn't require
any key at all.
Sending the encrypted password to the server doesn't help us. We're
already using SSL to send the Username/Password and all the other data, so
it's "safe" in transit. If we send the encrypted password, then there's
NO reason in the world to even HAVE an unencrypted password! And someone
could still see the ENCRYPTED password lying in the settings file and use
that directly.
I just want to make it a --little-- more difficult for someone that has
access to the machine to be able to send bad data to the server. SSL
provides some protection, though we don't authenticate peers: we only
ensure encrypted transfer: server provides valid PrivateKey and Cert,
client QSslSocket says "OK" and sends data. If I add peer authentication,
then client needs a PrivateKey(?) and a Cert(?), which would be stored in
diskfiles (just as easy for intruders to find as a Password) or in the app
source-code (a little harder to find).
I just want to hide the password from casual observers. Obfuscation (like
Base64) is generally too easy to undo; we want real encryption, but not
hyper-security. :)
The QSslSocket stuff is -somehow- applying encryption to the data before
it sends it over TCP. So it must be possible -somehow- to encrypt a
string WITHOUT sending it out. That's really all I want to do here.
So... Is there some Qt interface that will provide this? Or is there a
fairly simple OpenSSL API call I can make to do this? (OpenSSL is already
linked into the app because we use QSslSocket.)
Mike
On Wed, 31 Oct 2007 16:59:06 -0500, Chris Thompson
<cthompson@xxxxxxxxxxxxxxx> wrote:
> On October 31, 2007 03:52:02 pm Mike Broida wrote:
>> I have a non-interactive client app that sends Username/Password to a
>> server, followed by some data. The connection itself is through
>> QSslSocket, so all of that is sufficiently secure.
>>
>> But the Username/Password are STORED on the client in a QSettings .ini
>> file. I would like to make the Password at least a little more secure
>> by
>> encrypting it before putting it in the QSettings .ini file. Base64
>> isn't
>> quite good enough: anyone can undo that "encryption".
>>
>> I need a way for an app with a built in key/passphrase to encrypt the
>> Password string before putting it in the QSettings .ini file, and
>> decrypt
>> it after getting it from that file. The decrypted Password would then
>> be
>> sent to the server.
>>
>> But I can't find ANY way in Qt to do something as simple as:
>> QString unEncryptedValue("clearPassword");
>> QString encryptedValue = ?????.encrypt(unEncryptedValue,
>> useThisKey);
>>
>> The only encryption/decryption I can find is in SSL-related stuff, all
>> for
>> sending through QSslSocket, and in QCryptographicHash, only for getting
>> a
>> "digest" of the input and that's a one-way thing.
>> All the encode/decode I can find is related to character sets (Unicode,
>> ASCII, etc).
>>
>> Any pointers???
>>
>> Mike
>
> This is basically impossible to do securely. You would need to store the
> encryption key as part of the application. You say that Base64 isn't
> good
> enough because anyone could undo that "encryption". Given that you will
> need
> to store any encryption key as part of the app, all other methods are
> essentially identical, they just may not be quite so trivial.
--
[ signature omitted ]
You can obfuscate your password using the Tiny Encryption Algorithm. It's
real encryption but all it'll do is obfuscate your password. Seems you have
a reasonable understanding of this, though.
The algorithm is given at:
http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
It's only a very few lines of code, though it may require some work to get it
integrated into your Qt app.
Not the best encryption algorithm on the planet but it's nice and short.
Anyone breaking your password will have recovered the encryption key from
your running application rather than breaking the algorithm itself.
On October 31, 2007 05:47:04 pm Mike Broida wrote:
> We aren't looking for -perfect- security. It's not OpenSource: users have
> no access to the source-code. The encryption key would be in the
> source-code, probably separated into substrings scattered around so it's
> not trivial to find it by looking at the executable (which is all the
> end-user will have). Yes, a determined person could decompile the app,
> trace through it to see how we build the key from the substrings, and find
> those substrings. But that's not what we're worried about; the benefits
> of gaining access to the data (or to send bad data to the server) don't
> justify them expending even one-percent of that effort to get it. :) We
> just don't want someone to see the Password lying unencrypted in the
> settings file. Base64 is too easy to unencode because it doesn't require
> any key at all.
>
> Sending the encrypted password to the server doesn't help us. We're
> already using SSL to send the Username/Password and all the other data, so
> it's "safe" in transit. If we send the encrypted password, then there's
> NO reason in the world to even HAVE an unencrypted password! And someone
> could still see the ENCRYPTED password lying in the settings file and use
> that directly.
>
> I just want to make it a --little-- more difficult for someone that has
> access to the machine to be able to send bad data to the server. SSL
> provides some protection, though we don't authenticate peers: we only
> ensure encrypted transfer: server provides valid PrivateKey and Cert,
> client QSslSocket says "OK" and sends data. If I add peer authentication,
> then client needs a PrivateKey(?) and a Cert(?), which would be stored in
> diskfiles (just as easy for intruders to find as a Password) or in the app
> source-code (a little harder to find).
>
> I just want to hide the password from casual observers. Obfuscation (like
> Base64) is generally too easy to undo; we want real encryption, but not
> hyper-security. :)
>
> The QSslSocket stuff is -somehow- applying encryption to the data before
> it sends it over TCP. So it must be possible -somehow- to encrypt a
> string WITHOUT sending it out. That's really all I want to do here.
>
> So... Is there some Qt interface that will provide this? Or is there a
> fairly simple OpenSSL API call I can make to do this? (OpenSSL is already
> linked into the app because we use QSslSocket.)
>
> Mike
>
> On Wed, 31 Oct 2007 16:59:06 -0500, Chris Thompson
>
> <cthompson@xxxxxxxxxxxxxxx> wrote:
> > On October 31, 2007 03:52:02 pm Mike Broida wrote:
> >> I have a non-interactive client app that sends Username/Password to a
> >> server, followed by some data. The connection itself is through
> >> QSslSocket, so all of that is sufficiently secure.
> >>
> >> But the Username/Password are STORED on the client in a QSettings .ini
> >> file. I would like to make the Password at least a little more secure
> >> by
> >> encrypting it before putting it in the QSettings .ini file. Base64
> >> isn't
> >> quite good enough: anyone can undo that "encryption".
> >>
> >> I need a way for an app with a built in key/passphrase to encrypt the
> >> Password string before putting it in the QSettings .ini file, and
> >> decrypt
> >> it after getting it from that file. The decrypted Password would then
> >> be
> >> sent to the server.
> >>
> >> But I can't find ANY way in Qt to do something as simple as:
> >> QString unEncryptedValue("clearPassword");
> >> QString encryptedValue = ?????.encrypt(unEncryptedValue,
> >> useThisKey);
> >>
> >> The only encryption/decryption I can find is in SSL-related stuff, all
> >> for
> >> sending through QSslSocket, and in QCryptographicHash, only for getting
> >> a
> >> "digest" of the input and that's a one-way thing.
> >> All the encode/decode I can find is related to character sets (Unicode,
> >> ASCII, etc).
> >>
> >> Any pointers???
> >>
> >> Mike
> >
> > This is basically impossible to do securely. You would need to store the
> > encryption key as part of the application. You say that Base64 isn't
> > good
> > enough because anyone could undo that "encryption". Given that you will
> > need
> > to store any encryption key as part of the app, all other methods are
> > essentially identical, they just may not be quite so trivial.
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body. List archive and information:
> http://lists.trolltech.com/qt-interest/
--
[ signature omitted ]
Seems pretty reasonable. One question, though.
Are you trying to hide the password from the user, or the user's friends
and neighbors?
If the latter, can't you just make sure the .ini file is only readable
by the user?
Chris Thompson wrote:
> You can obfuscate your password using the Tiny Encryption Algorithm. It's
> real encryption but all it'll do is obfuscate your password. Seems you have
> a reasonable understanding of this, though.
>
> The algorithm is given at:
> http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
> It's only a very few lines of code, though it may require some work to get it
> integrated into your Qt app.
>
> Not the best encryption algorithm on the planet but it's nice and short.
> Anyone breaking your password will have recovered the encryption key from
> your running application rather than breaking the algorithm itself.
>
> On October 31, 2007 05:47:04 pm Mike Broida wrote:
>
>> We aren't looking for -perfect- security. It's not OpenSource: users have
>> no access to the source-code. The encryption key would be in the
>> source-code, probably separated into substrings scattered around so it's
>> not trivial to find it by looking at the executable (which is all the
>> end-user will have). Yes, a determined person could decompile the app,
>> trace through it to see how we build the key from the substrings, and find
>> those substrings. But that's not what we're worried about; the benefits
>> of gaining access to the data (or to send bad data to the server) don't
>> justify them expending even one-percent of that effort to get it. :) We
>> just don't want someone to see the Password lying unencrypted in the
>> settings file. Base64 is too easy to unencode because it doesn't require
>> any key at all.
>>
>> Sending the encrypted password to the server doesn't help us. We're
>> already using SSL to send the Username/Password and all the other data, so
>> it's "safe" in transit. If we send the encrypted password, then there's
>> NO reason in the world to even HAVE an unencrypted password! And someone
>> could still see the ENCRYPTED password lying in the settings file and use
>> that directly.
>>
>> I just want to make it a --little-- more difficult for someone that has
>> access to the machine to be able to send bad data to the server. SSL
>> provides some protection, though we don't authenticate peers: we only
>> ensure encrypted transfer: server provides valid PrivateKey and Cert,
>> client QSslSocket says "OK" and sends data. If I add peer authentication,
>> then client needs a PrivateKey(?) and a Cert(?), which would be stored in
>> diskfiles (just as easy for intruders to find as a Password) or in the app
>> source-code (a little harder to find).
>>
>> I just want to hide the password from casual observers. Obfuscation (like
>> Base64) is generally too easy to undo; we want real encryption, but not
>> hyper-security. :)
>>
>> The QSslSocket stuff is -somehow- applying encryption to the data before
>> it sends it over TCP. So it must be possible -somehow- to encrypt a
>> string WITHOUT sending it out. That's really all I want to do here.
>>
>> So... Is there some Qt interface that will provide this? Or is there a
>> fairly simple OpenSSL API call I can make to do this? (OpenSSL is already
>> linked into the app because we use QSslSocket.)
>>
>> Mike
>>
>> On Wed, 31 Oct 2007 16:59:06 -0500, Chris Thompson
>>
>> <cthompson@xxxxxxxxxxxxxxx> wrote:
>>
>>> On October 31, 2007 03:52:02 pm Mike Broida wrote:
>>>
>>>> I have a non-interactive client app that sends Username/Password to a
>>>> server, followed by some data. The connection itself is through
>>>> QSslSocket, so all of that is sufficiently secure.
>>>>
>>>> But the Username/Password are STORED on the client in a QSettings .ini
>>>> file. I would like to make the Password at least a little more secure
>>>> by
>>>> encrypting it before putting it in the QSettings .ini file. Base64
>>>> isn't
>>>> quite good enough: anyone can undo that "encryption".
>>>>
>>>> I need a way for an app with a built in key/passphrase to encrypt the
>>>> Password string before putting it in the QSettings .ini file, and
>>>> decrypt
>>>> it after getting it from that file. The decrypted Password would then
>>>> be
>>>> sent to the server.
>>>>
>>>> But I can't find ANY way in Qt to do something as simple as:
>>>> QString unEncryptedValue("clearPassword");
>>>> QString encryptedValue = ?????.encrypt(unEncryptedValue,
>>>> useThisKey);
>>>>
>>>> The only encryption/decryption I can find is in SSL-related stuff, all
>>>> for
>>>> sending through QSslSocket, and in QCryptographicHash, only for getting
>>>> a
>>>> "digest" of the input and that's a one-way thing.
>>>> All the encode/decode I can find is related to character sets (Unicode,
>>>> ASCII, etc).
>>>>
>>>> Any pointers???
>>>>
>>>> Mike
>>>>
>>> This is basically impossible to do securely. You would need to store the
>>> encryption key as part of the application. You say that Base64 isn't
>>> good
>>> enough because anyone could undo that "encryption". Given that you will
>>> need
>>> to store any encryption key as part of the app, all other methods are
>>> essentially identical, they just may not be quite so trivial.
>>>
>> --
>> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
>> "unsubscribe" in the subject or the body. List archive and information:
>> http://lists.trolltech.com/qt-interest/
>>
>
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
>
--
[ signature omitted ]
It's (currently) a Windows app. I don't think you can TRULY hide a file
there.
But, yes, more hiding it from "neighbors" than from the user. :)
On Wed, 31 Oct 2007 19:31:12 -0500, Peter Hackett <peter@xxxxxxxxxxxx>
wrote:
> Seems pretty reasonable. One question, though.
>
> Are you trying to hide the password from the user, or the user's friends
> and neighbors?
>
> If the latter, can't you just make sure the .ini file is only readable
> by the user?
>
> Chris Thompson wrote:
>> You can obfuscate your password using the Tiny Encryption Algorithm.
>> It's real encryption but all it'll do is obfuscate your password.
>> Seems you have a reasonable understanding of this, though.
>>
>> The algorithm is given at:
>> http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
>> It's only a very few lines of code, though it may require some work to
>> get it integrated into your Qt app.
>>
>> Not the best encryption algorithm on the planet but it's nice and
>> short. Anyone breaking your password will have recovered the
>> encryption key from your running application rather than breaking the
>> algorithm itself.
>>
>> On October 31, 2007 05:47:04 pm Mike Broida wrote:
>>
>>> We aren't looking for -perfect- security. It's not OpenSource: users
>>> have
>>> no access to the source-code. The encryption key would be in the
>>> source-code, probably separated into substrings scattered around so
>>> it's
>>> not trivial to find it by looking at the executable (which is all the
>>> end-user will have). Yes, a determined person could decompile the app,
>>> trace through it to see how we build the key from the substrings, and
>>> find
>>> those substrings. But that's not what we're worried about; the
>>> benefits
>>> of gaining access to the data (or to send bad data to the server) don't
>>> justify them expending even one-percent of that effort to get it. :)
>>> We
>>> just don't want someone to see the Password lying unencrypted in the
>>> settings file. Base64 is too easy to unencode because it doesn't
>>> require
>>> any key at all.
>>>
>>> Sending the encrypted password to the server doesn't help us. We're
>>> already using SSL to send the Username/Password and all the other
>>> data, so
>>> it's "safe" in transit. If we send the encrypted password, then
>>> there's
>>> NO reason in the world to even HAVE an unencrypted password! And
>>> someone
>>> could still see the ENCRYPTED password lying in the settings file and
>>> use
>>> that directly.
>>>
>>> I just want to make it a --little-- more difficult for someone that has
>>> access to the machine to be able to send bad data to the server. SSL
>>> provides some protection, though we don't authenticate peers: we only
>>> ensure encrypted transfer: server provides valid PrivateKey and Cert,
>>> client QSslSocket says "OK" and sends data. If I add peer
>>> authentication,
>>> then client needs a PrivateKey(?) and a Cert(?), which would be stored
>>> in
>>> diskfiles (just as easy for intruders to find as a Password) or in the
>>> app
>>> source-code (a little harder to find).
>>>
>>> I just want to hide the password from casual observers. Obfuscation
>>> (like
>>> Base64) is generally too easy to undo; we want real encryption, but not
>>> hyper-security. :)
>>>
>>> The QSslSocket stuff is -somehow- applying encryption to the data
>>> before
>>> it sends it over TCP. So it must be possible -somehow- to encrypt a
>>> string WITHOUT sending it out. That's really all I want to do here.
>>>
>>> So... Is there some Qt interface that will provide this? Or is there a
>>> fairly simple OpenSSL API call I can make to do this? (OpenSSL is
>>> already
>>> linked into the app because we use QSslSocket.)
>>>
>>> Mike
>>>
>>> On Wed, 31 Oct 2007 16:59:06 -0500, Chris Thompson
>>>
>>> <cthompson@xxxxxxxxxxxxxxx> wrote:
>>>
>>>> On October 31, 2007 03:52:02 pm Mike Broida wrote:
>>>>
>>>>> I have a non-interactive client app that sends Username/Password to a
>>>>> server, followed by some data. The connection itself is through
>>>>> QSslSocket, so all of that is sufficiently secure.
>>>>>
>>>>> But the Username/Password are STORED on the client in a QSettings
>>>>> .ini
>>>>> file. I would like to make the Password at least a little more
>>>>> secure
>>>>> by
>>>>> encrypting it before putting it in the QSettings .ini file. Base64
>>>>> isn't
>>>>> quite good enough: anyone can undo that "encryption".
>>>>>
>>>>> I need a way for an app with a built in key/passphrase to encrypt the
>>>>> Password string before putting it in the QSettings .ini file, and
>>>>> decrypt
>>>>> it after getting it from that file. The decrypted Password would
>>>>> then
>>>>> be
>>>>> sent to the server.
>>>>>
>>>>> But I can't find ANY way in Qt to do something as simple as:
>>>>> QString unEncryptedValue("clearPassword");
>>>>> QString encryptedValue = ?????.encrypt(unEncryptedValue,
>>>>> useThisKey);
>>>>>
>>>>> The only encryption/decryption I can find is in SSL-related stuff,
>>>>> all
>>>>> for
>>>>> sending through QSslSocket, and in QCryptographicHash, only for
>>>>> getting
>>>>> a
>>>>> "digest" of the input and that's a one-way thing.
>>>>> All the encode/decode I can find is related to character sets
>>>>> (Unicode,
>>>>> ASCII, etc).
>>>>>
>>>>> Any pointers???
>>>>>
>>>>> Mike
>>>>>
>>>> This is basically impossible to do securely. You would need to store
>>>> the
>>>> encryption key as part of the application. You say that Base64 isn't
>>>> good
>>>> enough because anyone could undo that "encryption". Given that you
>>>> will
>>>> need
>>>> to store any encryption key as part of the app, all other methods are
>>>> essentially identical, they just may not be quite so trivial.
>>>>
>>> --
>>> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
>>> "unsubscribe" in the subject or the body. List archive and information:
>>> http://lists.trolltech.com/qt-interest/
>>>
>>
>>
>> --
>> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
>> "unsubscribe" in the subject or the body.
>> List archive and information: http://lists.trolltech.com/qt-interest/
>>
>>
>>
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
--
[ signature omitted ]
Mike Broida wrote: > It's (currently) a Windows app. I don't think you can TRULY hide a file > there. > > But, yes, more hiding it from "neighbors" than from the user. :) You must be kidding right? Windows has a good ACL implementation. If you are not careful, you can "hide" your files from the system. ACL works for files as well as registry keys. - Adam -- [ signature omitted ]
On Thursday 01 November 2007, Mike Broida wrote: > We aren't looking for -perfect- security. It's not OpenSource: users > have no access to the source-code. Crackers are used to attacking binaries, so this is not a real obstacle. Action 1: use the file systems protection set the permissions of the file so that only the user himself can access it (see QFile::setPermissions). This protects from other users abusing the account of a collegue. Action 2: use some casual encoding (eg. Base64, rot13, etc.pp.) to obfuscate it. This protects the user from accidentally leaking the password while editing/viewing the file. > The encryption key would be in the > source-code, probably separated into substrings scattered around so it's > not trivial to find it by looking at the executable (which is all the > end-user will have). Good idea so far. > I just want to make it a --little-- more difficult for someone that has > access to the machine to be able to send bad data to the server. Now for the interesting question: whose password is it and from whom do you want to protect it? If it is the users password and you want to protect it from other users: why store it at all? Ask for it at the start of the session and then keep it in memory if it has to be sent repeatedly. If the application is some small helper that starts several dozen times a day, supply an agent application that keeps the password for the session and let the main application query the agent (see ssh-agent, or gpg-agent for examples). If it is the protocols password and you want to protect it from the user: I'm sorry to say - your protocol is broken by design. Redesign it so that the user owns the password. As the content industry is currently forced to learn: there is no amount of pixy dust, errm cryptography, that can hide data that the user controls from the user himself. There actually is an answer #3: your boss wants it that way and there is no way turning him. Action 1: use the file system to protect the data. Action 2: print out the email in which your boss demanded this nonsense. If you don't have an email: get one. If possible have him sign it. For every other stupid decision: have it in written form! (You can even impress him by calling it a "process".) This will save your backside when the protocol is eventually broken. Action 3: scatter some random data in your exe, use this data plus some salt value (eg. the current time when the password is stored) and hash it using QCryptographicHash. Xor the (properly truncated) result with the password and store the encrypted password and the salt value in the ini file. This is essentially a quite weak stream cipher (it should be approx. as safe as using TEA with a compiled in key). It should be quite enough trouble for most attackers, it doesn't put much of a burden on you and its security should match approximately what is possible in this scenario anyway. Stream ciphers have the benefit that they don't require complicated signalling of the end of data since the key-stream is truncated to the data stream length. If you need more of the key-stream than QCryptographicHash can provide: count up the salt value and rehash (there are better methods, but we are talking pixy dust anyway). Konrad
Attachment:
Attachment:
pgpdTHWpXtPp5.pgp
Attachment:
Attachment:
pgplASZuSXW6K.pgp
Attachment:
Attachment:
pgpxE8YeUpBeY.pgp
Attachment:
Attachment:
pgpQWwFfX69t8.pgp
Description: PGP signature
Message 7 in thread
On Thu, 01 Nov 2007 04:49:19 -0500, Konrad Rosenbaum <konrad@xxxxxxxxx>
wrote:
> If it is the users password and you want to protect it from other users:
> why store it at all? Ask for it at the start of the session and then keep
> it in memory if it has to be sent repeatedly. If the application is some
> small helper that starts several dozen times a day, supply an agent
> application that keeps the password for the session and let the main
> application query the agent (see ssh-agent, or gpg-agent for examples).
Password is the user's, but this app is run as a service: no user
interaction, so I can't ask for a password, even occasionally. It will
startup at system boot (not at user login). The password is changeable
without rebuilding the app. So keeping it in a file is the best way I can
see.
> Action 3: scatter some random data in your exe, use this data plus some
> salt value (eg. the current time when the password is stored) and hash
> it using QCryptographicHash. Xor the (properly truncated) result with
> the password and store the encrypted password and the salt value in the
> ini file.
This sounds interesting. So encryption part is just the XOR with a
keyvalue (that the code rebuilds from less obvious parts). Then
decryption is just XORing the encrypted value with that keyvalue. Hmmm.
A bit of both encryption and obfuscation. Sounds like it might be
enough. :)
> If you need more of the key-stream than QCryptographicHash
> can provide: count up the salt value and rehash (there are better
> methods, but we are talking pixy dust anyway).
Ah, I see. The length of the output from QCryptographicHash must have
enough bits to XOR with the data to be encrypted. Shouldn't be a problem,
I think. This is just to encrypt one password locally, not to encrypt all
the data to the server (SSL will handle that).
Thanks!
Mike
--
[ signature omitted ]
Message 8 in thread
It seems like this conversation isn't taking into account the
http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
suggestion. The code is *really* small (and seems to be reasonably easy
to understand.) So small that I'll include it here:
void encrypt (unsigned long* v, unsigned long* k) {
unsigned long v0=v[0], v1=v[1], sum=0, i; //* set up *//
unsigned long delta=0x9e3779b9; //* a key schedule constant *//
unsigned long k0=k[0], k1=k[1], k2=k[2], k3=k[3]; //* cache key *//
for (i=0; i < 32; i++) { //* basic cycle start *//
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3); //* end cycle *//
}
v[0]=v0; v[1]=v1;
}
void decrypt (unsigned long* v, unsigned long* k) {
unsigned long v0=v[0], v1=v[1], sum=0xC6EF3720, i; //* set up *//
unsigned long delta=0x9e3779b9; //* a key schedule constant *//
unsigned long k0=k[0], k1=k[1], k2=k[2], k3=k[3]; //* cache key *//
for (i=0; i<32; i++) { //* basic cycle start *//
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta; //* end cycle *//
}
v[0]=v0; v[1]=v1;
}
Mike Broida wrote:
> On Thu, 01 Nov 2007 04:49:19 -0500, Konrad Rosenbaum
> <konrad@xxxxxxxxx> wrote:
>
>> If it is the users password and you want to protect it from other
>> users: why store it at all? Ask for it at the start of the session
>> and then keep
>> it in memory if it has to be sent repeatedly. If the application is some
>> small helper that starts several dozen times a day, supply an agent
>> application that keeps the password for the session and let the main
>> application query the agent (see ssh-agent, or gpg-agent for examples).
>
> Password is the user's, but this app is run as a service: no user
> interaction, so I can't ask for a password, even occasionally. It
> will startup at system boot (not at user login). The password is
> changeable without rebuilding the app. So keeping it in a file is the
> best way I can see.
>
>> Action 3: scatter some random data in your exe, use this data plus
>> some salt value (eg. the current time when the password is stored)
>> and hash
>> it using QCryptographicHash. Xor the (properly truncated) result with
>> the password and store the encrypted password and the salt value in the
>> ini file.
>
> This sounds interesting. So encryption part is just the XOR with a
> keyvalue (that the code rebuilds from less obvious parts). Then
> decryption is just XORing the encrypted value with that keyvalue.
> Hmmm. A bit of both encryption and obfuscation. Sounds like it might
> be enough. :)
>
>> If you need more of the key-stream than QCryptographicHash
>> can provide: count up the salt value and rehash (there are better
>> methods, but we are talking pixy dust anyway).
>
> Ah, I see. The length of the output from QCryptographicHash must have
> enough bits to XOR with the data to be encrypted. Shouldn't be a
> problem, I think. This is just to encrypt one password locally, not
> to encrypt all the data to the server (SSL will handle that).
>
> Thanks!
> Mike
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
--
[ signature omitted ]
Message 9 in thread
Someone else did suggest it. I've looked at it, and we -might- go that
direction.
Thanks!
On Thu, 01 Nov 2007 11:56:31 -0500, Peter Hackett <peter@xxxxxxxxxxxx>
wrote:
> It seems like this conversation isn't taking into account the
> http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
> suggestion. The code is *really* small (and seems to be reasonably easy
> to understand.) So small that I'll include it here:
>
> void encrypt (unsigned long* v, unsigned long* k) {
> unsigned long v0=v[0], v1=v[1], sum=0, i; //* set up *//
> unsigned long delta=0x9e3779b9; //* a key
> schedule constant *//
> unsigned long k0=k[0], k1=k[1], k2=k[2], k3=k[3]; //* cache key
> *//
> for (i=0; i < 32; i++) { //* basic cycle
> start *//
> sum += delta;
> v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
> v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3); //* end
> cycle *//
> }
> v[0]=v0; v[1]=v1;
> }
> void decrypt (unsigned long* v, unsigned long* k) {
> unsigned long v0=v[0], v1=v[1], sum=0xC6EF3720, i; //* set up *//
> unsigned long delta=0x9e3779b9; //* a key
> schedule constant *//
> unsigned long k0=k[0], k1=k[1], k2=k[2], k3=k[3]; //* cache key
> *//
> for (i=0; i<32; i++) { //* basic
> cycle start *//
> v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
> v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
> sum -= delta; //* end cycle
> *//
> }
> v[0]=v0; v[1]=v1;
> }
>
>
>
> Mike Broida wrote:
>> On Thu, 01 Nov 2007 04:49:19 -0500, Konrad Rosenbaum <konrad@xxxxxxxxx>
>> wrote:
>>
>>> If it is the users password and you want to protect it from other
>>> users: why store it at all? Ask for it at the start of the session and
>>> then keep
>>> it in memory if it has to be sent repeatedly. If the application is
>>> some
>>> small helper that starts several dozen times a day, supply an agent
>>> application that keeps the password for the session and let the main
>>> application query the agent (see ssh-agent, or gpg-agent for examples).
>>
>> Password is the user's, but this app is run as a service: no user
>> interaction, so I can't ask for a password, even occasionally. It will
>> startup at system boot (not at user login). The password is changeable
>> without rebuilding the app. So keeping it in a file is the best way I
>> can see.
>>
>>> Action 3: scatter some random data in your exe, use this data plus
>>> some salt value (eg. the current time when the password is stored) and
>>> hash
>>> it using QCryptographicHash. Xor the (properly truncated) result with
>>> the password and store the encrypted password and the salt value in the
>>> ini file.
>>
>> This sounds interesting. So encryption part is just the XOR with a
>> keyvalue (that the code rebuilds from less obvious parts). Then
>> decryption is just XORing the encrypted value with that keyvalue.
>> Hmmm. A bit of both encryption and obfuscation. Sounds like it might
>> be enough. :)
>>
>>> If you need more of the key-stream than QCryptographicHash
>>> can provide: count up the salt value and rehash (there are better
>>> methods, but we are talking pixy dust anyway).
>>
>> Ah, I see. The length of the output from QCryptographicHash must have
>> enough bits to XOR with the data to be encrypted. Shouldn't be a
>> problem, I think. This is just to encrypt one password locally, not to
>> encrypt all the data to the server (SSL will handle that).
>>
>> Thanks!
>> Mike
>>
>> -- To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx
>> with "unsubscribe" in the subject or the body.
>> List archive and information: http://lists.trolltech.com/qt-interest/
>>
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
--
[ signature omitted ]
Message 10 in thread
On Thursday 01 November 2007, Peter Hackett wrote:
> It seems like this conversation isn't taking into account the
> http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
> suggestion. The code is *really* small (and seems to be reasonably easy
> to understand.) So small that I'll include it here:
Yes, according to Wikipedia the algorithm seems to be sufficient for the
purpose. I would not recommend to use it under any other circumstances. A
strength of 32 bit is clearly not enough for any serious encryption.
A few warnings about the code you provided:
1) you should use quint32 instead of unsigned long, otherwise it will not
work on 64bit systems (eg. some Windows versions on x86_64 hardware(*)).
(*)Never say never! The next system is just one compile away and when it is
time for it, it needs to be done within a day - the customer wanted it last
week and is already calling every hour or so.
Better add this to your code to be warned:
#if sizeof(quint32) != 4
#error No pure 32bit integer available!
#endif
2) It requires some skill in coding, since it works in blocks of 64bit with
32bit words. Simple pointer conversion will not work and length should be
checked! Hint: QByteArray works with unsigned chars which become very nasty
if they contain non-ASCII characters (>=0x80) and are converted to bigger
ints...
3) It is a block cipher. Hence it needs an end-marker. If NUL-bytes (0x00)
are not allowed in passwords this would be the easiest marker, otherwise
cryptographic protocols usually append 0x80 to the clear data and fill the
remainder of the block with 0x00 bytes - this way you can look from the
back, throw away all 0x00 bytes until 0x80 is reached, throw away 0x80 as
well and use the remainder.
4) You should follow the Wikipedia link to the test vectors and use them on
your implementation on all your target platforms in order to make sure you
did not make any mistakes.
All this does not need extraordinary knowledge in cryptography, but at least
a bit of experience which I would not like to gain on a work project that
needs to be done yesterday... ;-)
Konrad
Description: PGP signature
Message 11 in thread
On Thursday 01 November 2007, Mike Broida wrote:
> > Action 3: scatter some random data in your exe, use this data plus some
> > salt value (eg. the current time when the password is stored) and hash
> > it using QCryptographicHash. Xor the (properly truncated) result with
> > the password and store the encrypted password and the salt value in the
> > ini file.
>
> This sounds interesting. So encryption part is just the XOR with a
> keyvalue (that the code rebuilds from less obvious parts). Then
> decryption is just XORing the encrypted value with that keyvalue. Hmmm.
> A bit of both encryption and obfuscation. Sounds like it might be
> enough. :)
Well, this is how all stream-ciphers work: you have an algorithm that
generates a stream of bytes (key-stream) from a key (and often an
additional Initialization Vector - IV, or salt). Then you xor this stream
with the clear text data. The strength of a stream cipher depends on how
easy it is to guess the key from the key-stream and how easy it is to guess
any byte in the stream from preceding or following bytes.
One of the beauties of stream ciphers is that they are symmetrical: you use
the same key and algorithm for decryption. One of the dangers is that you
should never use the same key twice or you risk to reveal information about
the encrypted data:
encrypted1 = data1 xor keystream
encrypted2 = data2 xor keystream
encrypted1 xor encrypted2 == data1 xor data2
That's why I proposed to use a "salt" value.
The algorithm I proposed is directly dependent on the strength of the hash.
If the hash is perfect then the cipher should be pretty strong (approx. as
strong as the hash). Unfortunately there are no perfect hashes (esp. not
those in Qt), so the strength of the cipher decreases at least as much as
the strength of the hash is different from "perfect".
A little warning on the side: this kind of hash-based stream ciphers has not
been researched very much, since they are slower than genuine stream
ciphers.
Ok, since the "TEA faction" provided some code, here is some code how the
hash-based-stream-cipher should work:
//we assume that this is the password:
QByteArray pwd= .... /*get it from some configuration GUI*/;
//get key data
QByteArray key= .... /*get some bytes scattered throughout the exe*/;
QByteArray salt=QDateTime::currentDateTime().toString().toAscii();
//generate key stream
QByteArray kstream;
for(int ctr=0;kstream.size()<pwd.size();ctr++){
//unfortunately SHA1 is the strongest Hash available
QCryptographicHash hash(QCryptographicHash::Sha1);
//add key/salt
hash.addData(key);
hash.addData(salt);
//add counter so that blocks of keystream are different
//do this the complicted way to be portable:
QByteArray bctr;
bctr.append((char)((ctr>>24)&0xff));
bctr.append((char)((ctr>>16)&0xff));
bctr.append((char)((ctr>>8)&0xff));
bctr.append((char)(ctr&0xff));
hash.addData(bctr);
//append to key stream
kstream+=hash.result();
}
kstream.truncate(pwd.size());
//encrypt
for(int i=0;i<pwd.size();i++)
pwd[i] ^= kstream[i];
//store
QSettings ini("c:\\my\\ini\\file.ini",QSettings::IniFormat);
ini.setValue("pwdsalt",salt);
ini.setValue("encryptedpwd",pwd);
For decryption you simply get the salt and encrypted password from the ini
file and then run the same algorithm. (Xor is symmetric.)
Konrad
Description: PGP signature
Message 12 in thread
Thank you for the example code! It makes it clear what you meant, and it
will save me a lot of fooling around trying to create the same structure.
:)
On Thu, 01 Nov 2007 13:54:01 -0500, Konrad Rosenbaum <konrad@xxxxxxxxx>
wrote:
> On Thursday 01 November 2007, Mike Broida wrote:
>> > Action 3: scatter some random data in your exe, use this data plus
>> some
>> > salt value (eg. the current time when the password is stored) and hash
>> > it using QCryptographicHash. Xor the (properly truncated) result with
>> > the password and store the encrypted password and the salt value in
>> the
>> > ini file.
>>
>> This sounds interesting. So encryption part is just the XOR with a
>> keyvalue (that the code rebuilds from less obvious parts). Then
>> decryption is just XORing the encrypted value with that keyvalue. Hmmm.
>> A bit of both encryption and obfuscation. Sounds like it might be
>> enough. :)
>
> Well, this is how all stream-ciphers work: you have an algorithm that
> generates a stream of bytes (key-stream) from a key (and often an
> additional Initialization Vector - IV, or salt). Then you xor this stream
> with the clear text data. The strength of a stream cipher depends on how
> easy it is to guess the key from the key-stream and how easy it is to
> guess
> any byte in the stream from preceding or following bytes.
>
> One of the beauties of stream ciphers is that they are symmetrical: you
> use
> the same key and algorithm for decryption. One of the dangers is that you
> should never use the same key twice or you risk to reveal information
> about
> the encrypted data:
>
> encrypted1 = data1 xor keystream
> encrypted2 = data2 xor keystream
> encrypted1 xor encrypted2 == data1 xor data2
>
> That's why I proposed to use a "salt" value.
>
> The algorithm I proposed is directly dependent on the strength of the
> hash.
> If the hash is perfect then the cipher should be pretty strong (approx.
> as
> strong as the hash). Unfortunately there are no perfect hashes (esp. not
> those in Qt), so the strength of the cipher decreases at least as much as
> the strength of the hash is different from "perfect".
>
> A little warning on the side: this kind of hash-based stream ciphers has
> not
> been researched very much, since they are slower than genuine stream
> ciphers.
>
> Ok, since the "TEA faction" provided some code, here is some code how the
> hash-based-stream-cipher should work:
>
> //we assume that this is the password:
> QByteArray pwd= .... /*get it from some configuration GUI*/;
>
> //get key data
> QByteArray key= .... /*get some bytes scattered throughout the exe*/;
> QByteArray salt=QDateTime::currentDateTime().toString().toAscii();
>
> //generate key stream
> QByteArray kstream;
> for(int ctr=0;kstream.size()<pwd.size();ctr++){
> //unfortunately SHA1 is the strongest Hash available
> QCryptographicHash hash(QCryptographicHash::Sha1);
> //add key/salt
> hash.addData(key);
> hash.addData(salt);
> //add counter so that blocks of keystream are different
> //do this the complicted way to be portable:
> QByteArray bctr;
> bctr.append((char)((ctr>>24)&0xff));
> bctr.append((char)((ctr>>16)&0xff));
> bctr.append((char)((ctr>>8)&0xff));
> bctr.append((char)(ctr&0xff));
> hash.addData(bctr);
> //append to key stream
> kstream+=hash.result();
> }
> kstream.truncate(pwd.size());
>
> //encrypt
> for(int i=0;i<pwd.size();i++)
> pwd[i] ^= kstream[i];
>
> //store
> QSettings ini("c:\\my\\ini\\file.ini",QSettings::IniFormat);
> ini.setValue("pwdsalt",salt);
> ini.setValue("encryptedpwd",pwd);
>
>
> For decryption you simply get the salt and encrypted password from the
> ini
> file and then run the same algorithm. (Xor is symmetric.)
>
>
>
> Konrad
--
[ signature omitted ]
Message 13 in thread
Mike Broida wrote:
> I just want to make it a --little-- more difficult for someone that has
> access to the machine to be able to send bad data to the server. SSL
> provides some protection, though we don't authenticate peers: we only
> ensure encrypted transfer: server provides valid PrivateKey and Cert,
> client QSslSocket says "OK" and sends data. If I add peer
> authentication, then client needs a PrivateKey(?) and a Cert(?), which
> would be stored in diskfiles (just as easy for intruders to find as a
> Password) or in the app source-code (a little harder to find).
Use client authentication to protect your server, if public server.
Otherwise anyone can connect to the machine. With client authentication,
you are preventing anyone from connecting to the server and using a flaw
in the client-server protocol. Furthermore, a password is easily
crackable. A SSL client authentication is like a few 1000s character
password - not really brute-force anymore because someone wanted test123
password.
As for obfuscieted password storage (eg. database or private key), well,
I guess you can just create a large string in program then just XOR it
with the password using some algorithm. But that would only prevent
automatic password retrieval and not much better than base64.
- Adam
--
[ signature omitted ]
Message 14 in thread
On Thursday 01 November 2007, Adam M wrote:
> Use client authentication to protect your server, if public server.
> Otherwise anyone can connect to the machine. With client authentication,
> you are preventing anyone from connecting to the server and using a flaw
> in the client-server protocol.
On the other hand you risk to implement a flaw in your handling of client
certificate authentication.
And good luck with setting up the necessary PKI... ;-)
> Furthermore, a password is easily
> crackable.
Depends on the password.
> A SSL client authentication is like a few 1000s character
> password - not really brute-force anymore because someone wanted test123
> password.
Ouch. Please read a bit of real cryptographic literature. I can recommend
Schneier for starters.
A normal SSL-key contains 1024 bit keys.
Let's assume for a completely insane moment that this gives you 1024 bits of
security. Each character of an english text contains approximately 1.2 bits
of entropy (less if it is a political speech) - that makes the key
equivalent to 853 characters, not thousands of characters.
Now back to reality: a good 1024 bit key - RSA, DSA or Elgamal generated
with a decent cryptographic random generator - gives you approximately the
same security as a 128 bit cipher or hash, or a 106 character password
(with normal english text), or 16 bytes of pure random(*) noise.
(*)I refer to cryptographic random here. math.h's rand() function does not
count.
[Disclaimer: These estimations are losely based on the estimations used in
Schneiers "Practical Cryptography". He is the crypto guru, I'm merely a
reader...]
Konrad
Description: PGP signature
Message 15 in thread
Thanks for your reply. Please see my response to Chris Thompson's reply
to my original post. If that doesn't respond to your message, please post
again. :)
On Wed, 31 Oct 2007 17:38:44 -0500, Andreas Pakulat <apaku@xxxxxx> wrote:
> On Mittwoch, 31. Oktober 2007, Mike Broida wrote:
>> I have a non-interactive client app that sends Username/Password to a
>> server, followed by some data. The connection itself is through
>> QSslSocket, so all of that is sufficiently secure.
>>
>> But the Username/Password are STORED on the client in a QSettings
>> .ini file. I would like to make the Password at least a little more
>> secure by encrypting it before putting it in the QSettings .ini file.
>> Base64 isn't quite good enough: anyone can undo that "encryption".
>>
>> I need a way for an app with a built in key/passphrase to encrypt the
>> Password string before putting it in the QSettings .ini file, and
>> decrypt it after getting it from that file. The decrypted Password
>> would then be sent to the server.
>>
>> But I can't find ANY way in Qt to do something as simple as:
>> QString unEncryptedValue("clearPassword");
>> QString encryptedValue = ?????.encrypt(unEncryptedValue,
>> useThisKey);
>>
>> The only encryption/decryption I can find is in SSL-related stuff,
>> all for sending through QSslSocket, and in QCryptographicHash, only
>> for getting a "digest" of the input and that's a one-way thing.
>> All the encode/decode I can find is related to character sets
>> (Unicode, ASCII, etc).
>
> If you can't change the server to store a hash of the password instead
> of storing the real password then Qt can't help you. There's nothing in
> Qt that works like crypt() or stuff like ssh-keygen or creating a gpg
> key. You could try to look into QCA, maybe they provide ways of
> creating and storing a key to encrypt your information. Of course then
> you'd have to store the key somehow and that again means anybody can
> just get the key and the encrypted password and restore the original.
>
> Andreas
>
--
[ signature omitted ]