> From: owner-openssl-us...@openssl.org On Behalf Of pkumarn > Sent: Tuesday, 20 March, 2012 00:36
> Thanks a lot Dave for pointing out few things which i need to > take care. By > the way as this is not complete code, original code already > has taken care > of few things. > > Now coming to the original question, how do i make sure > PKCS5_PBKDF2_HMAC_SHA1() is generating the correct result of > my i/p data? > When i input RAND_bytes() data into PKCS5_PBKDF2_HMAC_SHA1(), i get a > different result but when the same is converted to ASCII > (human readable > format), i get a different result. ... > Use the correct input to _PBKDF2_ and you get the correct output. Or more exactly, since there are a huge number of possible input sets (pw + salt + niter) and corresponding output key values, make sure that decrypt uses the *same* derivation inputs as encrypt did. You seem to be not understanding some of my answers; either you are using standard terminology differently, or misunderstanding how characters work in C. So let me start from the basics, even if this may be repetitive. 'char' in C or its variants 'signed char' and 'unsigned char' are actually a byte of storage, which is at least 8 bits and on current-day machines you are likely to program (like PCs and Macs) exactly 8 bits. It can contain a small integer: 0..255 for unsigned 8 bits or -128..-127 for signed 8 bits two's complement. (C also allows ones' complement and sign-and-magnitude, but no machines you will use do so.) This small integer *optionally* can be and *usually* is the codepoint for a character in a character code like ASCII. (C doesn't require ASCII, but the machines you will use do have either ASCII or much more likely a superset of ASCII like Windows-1252 or ISO-8859-1.) In C a string is an array of char, each element containing a codepoint, terminated by null. For example on a typical ASCII-based machine: char xyz [4] = "Dog"; creates an array of 4 bytes, where xyz[0] = 68 = 0x44 // which is the ASCII codepoint for D xyz[1] = 111 = 0x6F // ditto o xyz[2] = 103 = 0x63 // ditto g xyz[3] = 0 // which is a null terminating byte/character C doesn't require that all byte values be codepoints for a character, and most commonly used codes have codepoints that either are totally unassigned or (now more common) aren't visible/displayable characters called graphics. (Space is displayable/printable but not a graphic.) Thus if you have arbitrary byte values, such as from RAND_bytes(a,n), they rarely (all) have meaning as ASCII graphics; they more often but not always have meaning as Windows-1252 or 8859-* graphics. To display such data 'losslessly' -- so that you can recover the exact bytes -- you need some conversion. You mention 'conversion to ASCII' as if there were one such conversion; there are many, and you want a conversion to the graphic subset of ASCII, not the several invisible control codes (aka control chars). The most common are hexadecimal (abbreviated hex) and base64 (with at least two major variants); you appear to want hex. If you convert 32 arbitrary bytes (your case) to hex, it is 64 characters (each of which is a hex digit). If you put that in a C string it also needs a null terminator. If you write it to a (text) file it may need a newline, and in some message formats it needs a tag or label etc. This converted hex string is different from the original data, and therefore using it for _PBKDF2_ will produce different (and wrong) output. Thus in general there are three approaches: - use arbitrary byte values for salt, in an environment where arbitrary values are okay. For example, in C you can write them to a disk file opened in binary mode and read them back unchanged. Some data formats, especially those using ASN.1 like PCKS#7/CMS and PKCS#12, can handle arbitrary bytes. - use arbitrary byte values for salt, convert them to a safe representation such as hex for transmission and/or storage, *and* convert back to the arbitrary bytes when re-used. - use byte values for salt that are restricted so they are *already* valid character codepoints. In my previous post I gave the simple example of 0x40-0x5F for ASCII. As I said this reduces the entropy of your salt, but it's still much more than needed and much more than plausible passwords. Choose one. *If* you want compability with the Javascript on the website you pointed to, as-is that apparently requires choice 3, although I think it can be modified to do hex for choice 2. I think Javascript itself can handle arbitrary bytes in strings but as far as I can tell they can't be input using a browser form as that code does, ruling out choice 1. ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager majord...@openssl.org