I use this function in order to encode an input:
Public Function encodeStrings(ByVal MyPass As String, ByVal MyUName As String) As String
Dim ENPass As String = Nothing
Dim password As String = (MyPass + MyUName)
Dim mhash As HashAlgorithm = New SHA1CryptoServiceProvider
Dim bytValue() As Byte = System.Text.Encoding.UTF8.GetBytes(password)
Dim bytHash() As Byte = mhash.ComputeHash(bytValue)
mhash.Clear()
ENPass = Convert.ToBase64String(bytHash)
Return ENPass
End Function
Now I need to decode this variable and get back the original string.
Does anyone know how to do that? I'm using VB.NET in my project.
No, there is no way to decode it. The SHA1CryptoServiceProvider implements a hashing algorithm. According to the MSDN:
Computes the SHA1 hash value for the input data...
SHA-1 is, by definition a hashing algorithm. According to the Wikipedia article:
In cryptography, SHA-1 is a cryptographic hash function designed by the United States National Security Agency and published by the United States NIST as a U.S. Federal Information Processing Standard. SHA-1 produces a 160-bit (20-byte) hash value. A SHA-1 hash value is typically expressed as a hexadecimal number, 40 digits long.
That is why it inherits from the HashAlgorithm base-class rather than the SymmetricAlgorithm base-class. Since it uses a hashing algorithm, that means that it is one-way encoded. The original string will always result in the same encrypted value, but there is no way to decrypt it to get back to the original value, since many different strings could result in that same encrypted value (although, with cryptographic hashing algorithms, such as SHA1, that is unfeasible).
If you think about it, that's the only thing that makes sense. If the SHA-1 algorithm always results in a hash code which is 20 bytes long, then that means you could encode a 1 gigabyte string and it would still only be 20 bytes long as an SHA-1 encrypted hash value. Surely you don't think that those 20 bytes contain all of the data that was originally stored in that 1 GB string. If that were the case, zipping files would be far more effective :)
Typically, when a cryptographic hashing algorithm is being used, it would be for something like storing a password. In that case, the issue is not how to decrypt the password, but rather, to encrypt the newly entered password and then compare the two encrypted values to see if they are the same. If the two encrypted values are the same, then you know that the user entered the right password. If the two encrypted values are not the same, then you know that it is incorrect (but you still don't know what the right password would be).
If you need a 2-way encryption algorithm, you need to use one which inherits from SymmetricAlgorithm, such as the AesCryptoServiceProvider class.
Related
When we are using cryptography always we are seeing byte arrays are being used instead of String values. But when we are looking at the techniques of most of the cryptography algorithms they uses hex values to do any operations. Eg. AES: MixColumns, SubBytes all these techniques(I suppose it uses) uses hex values to do those operations.
Can you explain how these byte arrays are used in these operations as hex values.
I have an assignment to develop a encryption algorithm , therefore any related sample codes would be much appropriate.
Every four digits of binary makes a hexadecimal digit, so, you can convert back and forth quite easily (see: http://en.wikipedia.org/wiki/Hexadecimal#Binary_conversion).
I don't think I full understand what you're asking, though.
The most important thing to understand about hexadecimal is that it is a system for representing numeric values, just like binary or decimal. It is nothing more than notation. As you may know, many computer languages allow you to specify numeric literals in a few different ways:
int a = 42;
int a = 0x2A;
These store the same value into the variable 'a', and a compiler should generate identical code for them. The difference between these two lines will be lost very early in the compilation process, because the compiler cares about the value you specified, and not so much about the representation you used to encode it in your source file.
Main takeaway: there is no such thing as "hex values" - there are just hex representations of values.
That all said, you also talk about string values. Obviously 42 != "42" != "2A" != 0x2A. If you have a string, you'll need to parse it to a numeric value before you do any computation with it.
Bytes, byte arrays and/or memory areas are normally displayed within an IDE (integrated development environment) and debugger as hexadecimals. This is because it is the most efficient and clear representation of a byte. It is pretty easy to convert them into bits (in his mind) for the experienced programmer. You can clearly see how XOR and shift works as well, for instance. Those (and addition) are the most common operations when doing symmetric encryption/hashing.
So it's unlikely that the program performs this kind of conversion, it's probably the environment you are in. That, and source code (which is converted to bytes at compile time) probably uses a lot of literals in hexadecimal notation as well.
Cryptography in general except hash functions is a method to convert data from one format to another mostly referred as cipher text using a secret key. The secret key can be applied to the cipher text to get the original data also referred as plain text. In this process data is processed in byte level though it can be bit level as well. The point here the text or strings which we referring to are in limited range of a byte. Example ASCII is defined in certain range in byte value of 0 - 255. In practical when a crypto operation is performed, the character is converted to equivalent byte and the using the key the process is performed. Now the outcome byte or bytes will most probably be out of range of human readable defined text like ASCII encoded etc. For this reason any data to which a crypto function is need to be applied is converted to byte array first. For example the text to be enciphered is "Hello how are you doing?" . The following steps shall be followed:
1. byte[] data = "Hello how are you doing?".getBytes()
2. Process encipher on data using key which is also byte[]
3. The output blob is referred as cipherTextBytes[]
4. Encryption is complete
5. Using Key[], a process is performed over cipherTextBytes[] which returns data bytes
6 A simple new String(data[]) will return string value of Hellow how are you doing.
This is a simple info which might help you to understand reference code and manuals better. In no way I am trying to explain you the core of cryptography here.
Ok after experimenting a little bit I found out that resin was calling my AbstractAuthenticator implementation "authenticate" method that takes an HttpDigestCredentials object instead of DigestCredentials (still don't know when is called each one of them) the problem is that HttpDigestCredentials doesn't have a getDigest() method, instead it has a getResponse() method which doesn't return a hash or at least not a comparable one.
After creating my own hash of [[user:realmassword] [nonce] [method:uri]] the hash is very different, in fact I think getResponse() does not return the digest but maybe the server response to the browser?.
Any way this is my debugging log :
USER:user:PASSWORD:password:REALM:resin:METHOD:GET:URI/appe/appe.html:NONCE:HsJzN+j+GQD:CNONCE:b1ad4fa1ba857cac88c202e64528bc0c:CLIENTDIGEST:[B#5dcd8bf7:SERVERDIGEST:I4DkRCh21YG2Mk14iTe+hg==
as you can see both the supposed client nonce is very very different from the server generated nonce, in fact the client nonce doesn't look like a MD5 hash at all.
Please has someone does this before? is there something missing in the HttpDigestCredentials? I know digest is barely used.
Please, I know about SSL but I can't have an SSL certificate just yet so don't tell me "Why don't you use SSL". ;)
Update:
Not sure if was the right thing to do but, as I read before Resin uses base64 format for hashes so I used apache commons-codec-1.6 to use encodeBase64String() method and now the hashes look alike but they are no the same.
I tried both passwordDigest.getPasswordDigest(a1+':'+nonce+':'+a2); passwordDigest.getPasswordDigest(a1+':'+nonce+':'+ncount+':'+cnonce+':'+qop+':'+a2);
and none of them gives the same hash as the one from HttpDigestCredentials.
Ok I finally made it . Weird subject Huh, only two views?
First, digest authentication makes use of user, password, realm, nonce, client_nonce, nonce_count, method, qop, and uri. Basically it uses the full digest spec. So in order to calculate the hash one must calculate it with all the whistles. Is just a matter of calling the get method for each one of the variables from HttpDigestCredentials except for user and password. The user will come in the form of a Principal and the password you must look for it yourself in your DB (in my case a DB4O database).
Then you must create a PasswordDigest object, that will take care of generate a hash with the getPasswordDigest() method, but first one must set the format to hex with passwordDigestObject.setFormat("hex").
There is one for the HA1 getPasswordDigest(user,password,realm) and there is another getPasswordDigest() method that takes just one string and one can use it to generate the rest of the hashes, both HA2 and with the previous hashed HA1 the final hash, of course with the nonce nonce_count client_nonce and qop, of course each one separated by a semicolon.
Then it comes the tricky part, although resin works with base64 encoding for digest when you call the getResponse() method from HttpDigestCredentials it returns a byte array (which is weird) so in order to compare it with your hash what I did was use the Hex.encodeHexString() method from org.apache.commons.codec.binary.Hex and pass the HttpCredentialsDigest getResponse() return value, and that will give a nice hex String to compare.
I was doing it the other way around, I was using the Base64 hash from PasswordDigest and converting the HttpDigestCredentials hash to Base64 and the resulting string were never the same.
Would like to know how to encrypt a file (lets say a .txt or .xml) with SHA512 hash ? How to proceed ?
What i would want to do is.. check if the file exist.. open it and then read it while unencrypting it.
Thanks!
That is not possible. SHA512 is a hashing algorithm, not an encryption algorithm.
If you want to get the hash for a file, you can use the SHA512 class.
Example:
Dim data As Byte() = File.ReadAllBytes("file.txt")
Dim result As Byte()
Dim sha As New SHA512Managed()
result = sha.ComputeHash(data)
A hash tells you the integrity of a series of bytes.
Encryption obscures or hides information.
To encrypt of file you could follow the MSDN tutorial:
http://msdn.microsoft.com/en-us/library/system.io.file.encrypt.aspx
Since you mention you want to do this 'on the fly', you could also select one of the .NET encryption algorithms and implement your own using the FileStream object:
http://support.microsoft.com/kb/307010
A google search reveals a wealth of information on the subject.
I'm working on a licensing system for my application. I'd like to put all licensing information (licensee name, expiration date, and enabled features) into an object, encrypt that object with a private key, then represent the encrypted data as a single text string which I can send via email to my customers.
I've managed to get the encrypted data into a byte stream, but I don't know how to convert that byte stream into a text value -- something that contains no control characters or whitespace. Can anyone offer advice on how to do that? I've been researching the Encoding class, but I can't find a text-only encoding.
I'm using Net 2.0 -- mostly VB, but I can do C# also.
Use a Base64Encoder to convert it to a text string that can be decoded with a Base64Decoder. It is great for representing arbitary binary data in a text friendly manner, only upper and lower case A-Z and 0-9 digits.
BinHex is an example of one way to do that. It may not be exactly what you want -- for example, you might want to encode your data such that it's impossible to inadvertently spell words in your string, and you may or may not care about maximizing the density of information. But it's an example that may help you come up with your own encoding.
I've found Base32 useful for license keys before. There are some C# implementations linked from this answer. My own license code is based on this implementation, which avoids ambiguous characters to make it easier to retype the keys.
How to encrypt a nsstring and store it in a file, and how to decrypt the same.
Please suggest me wat api's i shld use...
This is the function i used for encryptiong.
DES_cfb64_encrypt( ( unsigned char * ) pchInputData, ( unsigned char * ) pchOutCipher,
size, &schedule, &ParityKey, &no, DES_ENCRYPT );
I had to convert this to base64 so that i can store it in a file.
pstrResult = Base64encoding(size,( unsigned char * )pchOutCipher);
You can use gpgme
If you only need to support 10.5 or higher you can use the CommonCryptor API. The first comment to this post shows an example category for encrypting/decrypting NSData's:
http://iphonedevelopment.blogspot.com/2009/02/strong-encryption-for-cocoa-cocoa-touch.html
While not an API call, you could implement a simple XOR cipher. This is quick and simple to implement and depending on the characteristics of your string (i.e. if it is of fixed length) can be very secure. If you have a variable length string XOR encryption may not be secure enough depending on your needs. Have a look at the Wikipedia article.
If you are storing a password first decide whether or not you need to re-use the password or whether you just need to check that the user has entered the correct password.
If you just need to verify that the user has entered the correct password, then store the password using a hash, and compare the hash of the user input with the hash you have stored. If both hashes are equal, then the user has [probably] typed it correctly. See more information about hashes at Wikipedia.
If you need to re-use the password (i.e. for authenticating with other services, such as connecting to an Internet service), use Apple's Keychain service. If you are targeting the iPhone, then check out this related document.