Quantcast

.NET PasswordDeriveBytes

classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

.NET PasswordDeriveBytes

Ahmed Ashour-2
Dear All,

Using BC for J2ME, how to have the same behaviour as .NET
PasswordDeriveBytes?  As you see in the below code, the results are
different, notice that IterationCount is 100 by default.

In PasswordDeriveBytes docs, "This class uses an extension of the
PBKDF1 algorithm defined in the PKCS#5 v2.0 standard to derive bytes
suitable for use as key material from a password. The standard is
documented in IETF RRC 2898."


------------------------------------------------------------------------------------
            byte[] password = { 00, 01, 02, 03, 04, 05, 06, 07, 08,
09, 10, 11, 12, 13, 14, 15 };
            byte[] salt = System.Text.ASCIIEncoding.ASCII.GetBytes("MyTesting");
            PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, salt);
            byte[] key = pdb.GetBytes(32);
            byte[] iv = pdb.GetBytes(16);
            System.Console.WriteLine("PasswordDeriveBytes: Hash=" +
pdb.HashName + ", iterations=" + pdb.IterationCount);
            System.Console.WriteLine( "Key " + toHexString( key ) );
            System.Console.WriteLine( "IV " + toHexString( iv ) );
------------------------------------------------------------------------------------
                byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

                byte[] salt = PKCS5S2ParametersGenerator.PKCS5PasswordToBytes(
"MyTesting".toCharArray() );

                KDF1BytesGenerator generator = new KDF1BytesGenerator( new SHA1Digest() );
                generator.init( new KDFParameters( password, salt ) );

                byte[] key = new byte[32];
                generator.generateBytes( key, 0, key.length );
                System.out.println( "32 " + new String( Hex.encode( key ) ).toUpperCase() );
               
                byte[] iv = new byte[16];
                generator.generateBytes( iv, 0, iv.length );
                System.out.println( "16 " + new String( Hex.encode( iv ) ).toUpperCase() );
------------------------------------------------------------------------------------

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Ahmed Ashour-2
Dear Julius,

Thanks for your reply.

However: there is no KDF1BytesGenerator(Mac) constructor defined.

Also, given the below code, the results are still different:

Many thanks,
Ahmed Ashour
--------------------------------------------------------------------------------------
.NET code:

            byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15 };
            byte[] salt = System.Text.ASCIIEncoding.ASCII.GetBytes("MyTesting");
            PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, salt);
            byte[] key = pdb.GetBytes(32);
            byte[] iv = pdb.GetBytes(16);
            System.Console.WriteLine("PasswordDeriveBytes: Hash=" +
pdb.HashName + ", iterations=" + pdb.IterationCount);
            System.Console.WriteLine( "Key " + toHexString( key ) );
            System.Console.WriteLine( "IV " + toHexString( iv ) );
--------------------------------------------------------------------------------------
BC Code:
        byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
        byte[] salt = PKCS5S2ParametersGenerator.PKCS5PasswordToBytes(
"MyTesting".toCharArray() );
        PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
        gen.init( password, salt, 100 );

        ParametersWithIV params = (ParametersWithIV)
gen.generateDerivedParameters( 32*8, 16*8 );
        KeyParameter keyParam = (KeyParameter)params.getParameters();
        byte[] key = keyParam.getKey();
        System.out.println( "Key " + new String( Hex.encode( key ) ).toUpperCase() );
        System.out.println( "IV " + new String( Hex.encode( params.getIV() )
).toUpperCase() );
--------------------------------------------------------------------------------------
.NET Result:
Key 04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922
IV 89946D3662B3196860A8041FCD7E8DA4
--------------------------------------------------------------------------------------
BC Result:
Key 959997080DA25033877B055C51FC4C9198738E5F09ECAC5B6DBD2571C0CCD641
IV 4FDFB03A04EF74EE31BE71A1C6CEA662



On 2/23/07, Julius Davies <[hidden email]> wrote:

> Alternatively, perhaps the real problem is that you're using:
>
> new KDF1BytesGenerator( new SHA1Digest() );
>
>
> If this were possible, it might work for you:
>
> new KDF1BytesGenerator( new HMac(new SHA1Digest() ) );
>
> But I suspect it's not possible.
>
>
> On 2/22/07, Julius Davies <[hidden email]> wrote:
> > I think you're very close!
> >
> > PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
> > gen.init( password, salt, 100 );
> >
> > ParametersWithIV params;
> > params = (ParametersWithIV) gen.generateDerivedParameters( 32, 16 );
> > KeyParameter keyParam = (KeyParameter) params.getParameters();
> >
> > byte[] key = keyParam.getKey();
> > byte[] iv = params.getIV();
> >
> >
> >
> >
> > On 2/22/07, Ahmed Ashour <[hidden email]> wrote:
> > > Dear All,
> > >
> > > Using BC for J2ME, how to have the same behaviour as .NET
> > > PasswordDeriveBytes?  As you see in the below code, the results are
> > > different, notice that IterationCount is 100 by default.
> > >
> > > In PasswordDeriveBytes docs, "This class uses an extension of the
> > > PBKDF1 algorithm defined in the PKCS#5 v2.0 standard to derive bytes
> > > suitable for use as key material from a password. The standard is
> > > documented in IETF RRC 2898."
> > >
> > >
> > > ------------------------------------------------------------------------------------
> > >             byte[] password = { 00, 01, 02, 03, 04, 05, 06, 07, 08,
> > > 09, 10, 11, 12, 13, 14, 15 };
> > >             byte[] salt = System.Text.ASCIIEncoding.ASCII.GetBytes("MyTesting");
> > >             PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, salt);
> > >             byte[] key = pdb.GetBytes(32);
> > >             byte[] iv = pdb.GetBytes(16);
> > >             System.Console.WriteLine("PasswordDeriveBytes: Hash=" +
> > > pdb.HashName + ", iterations=" + pdb.IterationCount);
> > >             System.Console.WriteLine( "Key " + toHexString( key ) );
> > >             System.Console.WriteLine( "IV " + toHexString( iv ) );
> > > ------------------------------------------------------------------------------------
> > >                 byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
> > >
> > >                 byte[] salt = PKCS5S2ParametersGenerator.PKCS5PasswordToBytes(
> > > "MyTesting".toCharArray() );
> > >
> > >                 KDF1BytesGenerator generator = new KDF1BytesGenerator( new SHA1Digest() );
> > >                 generator.init( new KDFParameters( password, salt ) );
> > >
> > >                 byte[] key = new byte[32];
> > >                 generator.generateBytes( key, 0, key.length );
> > >                 System.out.println( "32 " + new String( Hex.encode( key ) ).toUpperCase() );
> > >
> > >                 byte[] iv = new byte[16];
> > >                 generator.generateBytes( iv, 0, iv.length );
> > >                 System.out.println( "16 " + new String( Hex.encode( iv ) ).toUpperCase() );
> > > ------------------------------------------------------------------------------------
> > >
> > >
> >
> >
> > --
> > yours,
> >
> > Julius Davies
> > 416-652-0183
> > http://juliusdavies.ca/
> >
>
>
> --
> yours,
>
> Julius Davies
> 416-652-0183
> http://juliusdavies.ca/
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Peter Dettman
In reply to this post by Ahmed Ashour-2
Hi Ahmed,

I think you should be using
org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator.

This bit of code agrees with your .NET code on the first 16 bytes
generated...

        byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15 };
        byte[] salt =
PKCS5S2ParametersGenerator.PKCS5PasswordToBytes("MyTesting".toCharArray());

        PKCS5S1ParametersGenerator generator = new
PKCS5S1ParametersGenerator(new SHA1Digest());
        generator.init(password, salt, 100);

        byte[] iv = ((KeyParameter)
generator.generateDerivedParameters(128)).getKey();
        System.out.println( "16 " + new
String(Hex.encode(iv)).toUpperCase() );

However, note that this class will fail if you try to derive  a key of
more than 20 bytes. See RFC 2898 5.1:

        "The length of the derived key is bounded by the length of the
hash function output, which is 16 octets for MD2 and MD5 and 20 octets
for SHA-1."

I guess when the docs describe PasswordDeriveBytes as extending PBKDF1,
they mean they ignore/modify this restriction.

Cheers,
Pete.

Ahmed Ashour wrote:

> Dear All,
>
> Using BC for J2ME, how to have the same behaviour as .NET
> PasswordDeriveBytes?  As you see in the below code, the results are
> different, notice that IterationCount is 100 by default.
>
> In PasswordDeriveBytes docs, "This class uses an extension of the
> PBKDF1 algorithm defined in the PKCS#5 v2.0 standard to derive bytes
> suitable for use as key material from a password. The standard is
> documented in IETF RRC 2898."
>
>
> ------------------------------------------------------------------------------------
>
>            byte[] password = { 00, 01, 02, 03, 04, 05, 06, 07, 08,
> 09, 10, 11, 12, 13, 14, 15 };
>            byte[] salt =
> System.Text.ASCIIEncoding.ASCII.GetBytes("MyTesting");
>            PasswordDeriveBytes pdb = new PasswordDeriveBytes(password,
> salt);
>            byte[] key = pdb.GetBytes(32);
>            byte[] iv = pdb.GetBytes(16);
>            System.Console.WriteLine("PasswordDeriveBytes: Hash=" +
> pdb.HashName + ", iterations=" + pdb.IterationCount);
>            System.Console.WriteLine( "Key " + toHexString( key ) );
>            System.Console.WriteLine( "IV " + toHexString( iv ) );
> ------------------------------------------------------------------------------------
>
>         byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
> 13, 14, 15 };
>
>         byte[] salt = PKCS5S2ParametersGenerator.PKCS5PasswordToBytes(
> "MyTesting".toCharArray() );
>
>         KDF1BytesGenerator generator = new KDF1BytesGenerator( new
> SHA1Digest() );
>         generator.init( new KDFParameters( password, salt ) );
>
>         byte[] key = new byte[32];
>         generator.generateBytes( key, 0, key.length );
>         System.out.println( "32 " + new String( Hex.encode( key )
> ).toUpperCase() );
>        
>         byte[] iv = new byte[16];
>         generator.generateBytes( iv, 0, iv.length );
>         System.out.println( "16 " + new String( Hex.encode( iv )
> ).toUpperCase() );
> ------------------------------------------------------------------------------------
>
>


smime.p7s (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Julius Davies
Sorry about my original!  I wasn't paying close enough attention.
"PKCS5S2ParametersGenerator" uses PBKDF2, not PBKDF1.

PBKDF1 isn't supposed be able to go beyond 20 bytes of "generated key":

http://www.ietf.org/rfc/rfc2898.txt
--------------------------------------------------
If dkLen > 16 for MD2 and MD5, or dkLen > 20 for SHA-1, output
"derived key too long" and stop.
--------------------------------------------------

I cannot for the life of me figure what the "extension" Microsoft has
added here to get it to go beyond 20 bytes.  PBKDF2 is for going
beyond 20 bytes, not PBKDF1!

Hopefully someone on the list can figure out how Microsoft generates
beyond 20 bytes using PBKDF1 so that we can interop.


FYI:  The BC results (using PBKDF2) are compatible with "openssl pkcs8
-topk8 -v2" !

--------------------------------------------------------------------------------------
BC Result:
Key 959997080DA25033877B055C51FC4C9198738E5F09ECAC5B6DBD2571C0CCD641
IV 4FDFB03A04EF74EE31BE71A1C6CEA662
--------------------------------------------------------------------------------------


yours,

Julius



On 2/22/07, Peter Dettman <[hidden email]> wrote:

> Hi Ahmed,
>
> I think you should be using
> org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator.
>
> This bit of code agrees with your .NET code on the first 16 bytes
> generated...
>
>         byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
> 13, 14, 15 };
>         byte[] salt =
> PKCS5S2ParametersGenerator.PKCS5PasswordToBytes("MyTesting".toCharArray());
>
>         PKCS5S1ParametersGenerator generator = new
> PKCS5S1ParametersGenerator(new SHA1Digest());
>         generator.init(password, salt, 100);
>
>         byte[] iv = ((KeyParameter)
> generator.generateDerivedParameters(128)).getKey();
>         System.out.println( "16 " + new
> String(Hex.encode(iv)).toUpperCase() );
>
> However, note that this class will fail if you try to derive  a key of
> more than 20 bytes. See RFC 2898 5.1:
>
>         "The length of the derived key is bounded by the length of the
> hash function output, which is 16 octets for MD2 and MD5 and 20 octets
> for SHA-1."
>
> I guess when the docs describe PasswordDeriveBytes as extending PBKDF1,
> they mean they ignore/modify this restriction.
>
> Cheers,
> Pete.
>
> Ahmed Ashour wrote:
> > Dear All,
> >
> > Using BC for J2ME, how to have the same behaviour as .NET
> > PasswordDeriveBytes?  As you see in the below code, the results are
> > different, notice that IterationCount is 100 by default.
> >
> > In PasswordDeriveBytes docs, "This class uses an extension of the
> > PBKDF1 algorithm defined in the PKCS#5 v2.0 standard to derive bytes
> > suitable for use as key material from a password. The standard is
> > documented in IETF RRC 2898."
> >
> >
> > ------------------------------------------------------------------------------------
> >
> >            byte[] password = { 00, 01, 02, 03, 04, 05, 06, 07, 08,
> > 09, 10, 11, 12, 13, 14, 15 };
> >            byte[] salt =
> > System.Text.ASCIIEncoding.ASCII.GetBytes("MyTesting");
> >            PasswordDeriveBytes pdb = new PasswordDeriveBytes(password,
> > salt);
> >            byte[] key = pdb.GetBytes(32);
> >            byte[] iv = pdb.GetBytes(16);
> >            System.Console.WriteLine("PasswordDeriveBytes: Hash=" +
> > pdb.HashName + ", iterations=" + pdb.IterationCount);
> >            System.Console.WriteLine( "Key " + toHexString( key ) );
> >            System.Console.WriteLine( "IV " + toHexString( iv ) );
> > ------------------------------------------------------------------------------------
> >
> >         byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
> > 13, 14, 15 };
> >
> >         byte[] salt = PKCS5S2ParametersGenerator.PKCS5PasswordToBytes(
> > "MyTesting".toCharArray() );
> >
> >         KDF1BytesGenerator generator = new KDF1BytesGenerator( new
> > SHA1Digest() );
> >         generator.init( new KDFParameters( password, salt ) );
> >
> >         byte[] key = new byte[32];
> >         generator.generateBytes( key, 0, key.length );
> >         System.out.println( "32 " + new String( Hex.encode( key )
> > ).toUpperCase() );
> >
> >         byte[] iv = new byte[16];
> >         generator.generateBytes( iv, 0, iv.length );
> >         System.out.println( "16 " + new String( Hex.encode( iv )
> > ).toUpperCase() );
> > ------------------------------------------------------------------------------------
> >
> >
>
>
>


--
yours,

Julius Davies
416-652-0183
http://juliusdavies.ca/

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Peter Dettman
The Mono project has the algorithm - see
http://svn.myrealbox.com/viewcvs/trunk/mcs/class/corlib/System.Security.Cryptography/PasswordDeriveBytes.cs?view=markup

Briefly, each 20 bytes (for SHA1) is generated according to the PBKDF1
algorithm, except for the final iteration:

- For first 20 bytes, last iteration is as normal.

- For subsequent 20 byte increments, the last iteration additionally
(before the normal update) updates the digest using the 'count' of
number of buffers so far (actually the bytes of the string
representation) i.e.:
            byte[] prefix = Integer.toString(count).getBytes();
            digest.update(prefix, 0, prefix.length);

- The algorithm is limited to 1000 * 20 bytes.

Also, note that subsequent calls to PasswordDeriveBytes.GetBytes
generate further bytes in the 'stream', rather than starting the
algorithm from scratch each time.

Oh, and Dave, I bet that wasn't in your list of guesses of the way they
could be doing this :o).

Cheers,
Pete.


P.S. I include my simplistic Java implementation of this algorithm below
(for generateDerivedParameters(int) only). This implementation seems to
produce the same output as the .NET class.


import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Hex;


public class PKCS5Test
{
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception
    {
        byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15 };
        byte[] salt =
PKCS5S1ParametersGenerator.PKCS5PasswordToBytes("MyTesting".toCharArray());

        PKCS5S1ParametersGenerator generator = new
PasswordDeriveBytes(new SHA1Digest());
        generator.init(password, salt, 100);

        byte[] key = ((KeyParameter)
generator.generateDerivedParameters(512)).getKey();
        System.out.println( "64 " + new
String(Hex.encode(key)).toUpperCase() );
    }

    static class PasswordDeriveBytes extends PKCS5S1ParametersGenerator
    {
        private final Digest d;

        private byte[] output = null;

        public PasswordDeriveBytes(Digest d)
        {
            super(d);
           
            this.d = d;
        }

        public CipherParameters generateDerivedParameters(
            int keySize)
        {
            keySize = keySize / 8;

            byte[] result = new byte[keySize];
            int done = 0;
            int count = 0;
            byte[] b = null;

            while (done < result.length)
            {
                if (b == null)
                {
                    b = generateInitialKey();
                }
                else if (++count < 1000)
                {
                    b = generateExtendedKey(++count);
                }
                else
                {
                    throw new RuntimeException("Exceeded limit");
                }

                int use = Math.min(b.length, result.length - done);
                System.arraycopy(b, 0, result, done, use);
                done += use;
            }

            return new KeyParameter(result);
        }

        private byte[] generateOutput()
        {
            byte[] digestBytes = new byte[d.getDigestSize()];

            d.update(password, 0, password.length);
            d.update(salt, 0, salt.length);
            d.doFinal(digestBytes, 0);

            for (int i = 1; i < (iterationCount - 1); i++)
            {
                d.update(digestBytes, 0, digestBytes.length);
                d.doFinal(digestBytes, 0);
            }

            return digestBytes;
        }

        private byte[] generateInitialKey()
        {
            output = generateOutput();
            d.update(output, 0, output.length);

            byte[] digestBytes = new byte[d.getDigestSize()];
            d.doFinal(digestBytes, 0);
            return digestBytes;
        }

        private byte[] generateExtendedKey(int count)
        {
            byte[] prefix = Integer.toString(count).getBytes();
            d.update(prefix, 0, prefix.length);
            d.update(output, 0, output.length);

            byte[] digestBytes = new byte[d.getDigestSize()];
            d.doFinal(digestBytes, 0);

            //System.err.println( "X: " + new
String(Hex.encode(digestBytes)).toUpperCase() );
            return digestBytes;
        }
    }
}


David Hook wrote:
> If you can send me some samples of longer keys I might be able to work
> it out - "assuming" they've followed the usual methods there's only a
> few ways they could be doing this.
>
> Regards,
>
> David
>  


smime.p7s (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

David Hook-4

Cool! (Yes, that saved a bit of head scratching). Minor suggestion for
anyone using this, with getBytes() it's probably a good idea to specify
"US-ASCII" as well.

I'll add a generator for this to the lightweight API.

Regards,

David

On Sat, 2007-02-24 at 18:27 +1100, Peter Dettman wrote:

> The Mono project has the algorithm - see
> http://svn.myrealbox.com/viewcvs/trunk/mcs/class/corlib/System.Security.Cryptography/PasswordDeriveBytes.cs?view=markup
>
> Briefly, each 20 bytes (for SHA1) is generated according to the PBKDF1
> algorithm, except for the final iteration:
>
> - For first 20 bytes, last iteration is as normal.
>
> - For subsequent 20 byte increments, the last iteration additionally
> (before the normal update) updates the digest using the 'count' of
> number of buffers so far (actually the bytes of the string
> representation) i.e.:
>             byte[] prefix = Integer.toString(count).getBytes();
>             digest.update(prefix, 0, prefix.length);
>
> - The algorithm is limited to 1000 * 20 bytes.
>
> Also, note that subsequent calls to PasswordDeriveBytes.GetBytes
> generate further bytes in the 'stream', rather than starting the
> algorithm from scratch each time.
>
> Oh, and Dave, I bet that wasn't in your list of guesses of the way they
> could be doing this :o).
>
> Cheers,
> Pete.
>
>
> P.S. I include my simplistic Java implementation of this algorithm below
> (for generateDerivedParameters(int) only). This implementation seems to
> produce the same output as the .NET class.
>
>
> import org.bouncycastle.crypto.CipherParameters;
> import org.bouncycastle.crypto.Digest;
> import org.bouncycastle.crypto.digests.SHA1Digest;
> import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
> import org.bouncycastle.crypto.params.KeyParameter;
> import org.bouncycastle.util.encoders.Hex;
>
>
> public class PKCS5Test
> {
>     /**
>      * @param args
>      */
>     public static void main(String[] args) throws Exception
>     {
>         byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
> 13, 14, 15 };
>         byte[] salt =
> PKCS5S1ParametersGenerator.PKCS5PasswordToBytes("MyTesting".toCharArray());
>
>         PKCS5S1ParametersGenerator generator = new
> PasswordDeriveBytes(new SHA1Digest());
>         generator.init(password, salt, 100);
>
>         byte[] key = ((KeyParameter)
> generator.generateDerivedParameters(512)).getKey();
>         System.out.println( "64 " + new
> String(Hex.encode(key)).toUpperCase() );
>     }
>
>     static class PasswordDeriveBytes extends PKCS5S1ParametersGenerator
>     {
>         private final Digest d;
>
>         private byte[] output = null;
>
>         public PasswordDeriveBytes(Digest d)
>         {
>             super(d);
>            
>             this.d = d;
>         }
>
>         public CipherParameters generateDerivedParameters(
>             int keySize)
>         {
>             keySize = keySize / 8;
>
>             byte[] result = new byte[keySize];
>             int done = 0;
>             int count = 0;
>             byte[] b = null;
>
>             while (done < result.length)
>             {
>                 if (b == null)
>                 {
>                     b = generateInitialKey();
>                 }
>                 else if (++count < 1000)
>                 {
>                     b = generateExtendedKey(++count);
>                 }
>                 else
>                 {
>                     throw new RuntimeException("Exceeded limit");
>                 }
>
>                 int use = Math.min(b.length, result.length - done);
>                 System.arraycopy(b, 0, result, done, use);
>                 done += use;
>             }
>
>             return new KeyParameter(result);
>         }
>
>         private byte[] generateOutput()
>         {
>             byte[] digestBytes = new byte[d.getDigestSize()];
>
>             d.update(password, 0, password.length);
>             d.update(salt, 0, salt.length);
>             d.doFinal(digestBytes, 0);
>
>             for (int i = 1; i < (iterationCount - 1); i++)
>             {
>                 d.update(digestBytes, 0, digestBytes.length);
>                 d.doFinal(digestBytes, 0);
>             }
>
>             return digestBytes;
>         }
>
>         private byte[] generateInitialKey()
>         {
>             output = generateOutput();
>             d.update(output, 0, output.length);
>
>             byte[] digestBytes = new byte[d.getDigestSize()];
>             d.doFinal(digestBytes, 0);
>             return digestBytes;
>         }
>
>         private byte[] generateExtendedKey(int count)
>         {
>             byte[] prefix = Integer.toString(count).getBytes();
>             d.update(prefix, 0, prefix.length);
>             d.update(output, 0, output.length);
>
>             byte[] digestBytes = new byte[d.getDigestSize()];
>             d.doFinal(digestBytes, 0);
>
>             //System.err.println( "X: " + new
> String(Hex.encode(digestBytes)).toUpperCase() );
>             return digestBytes;
>         }
>     }
> }
>
>
> David Hook wrote:
> > If you can send me some samples of longer keys I might be able to work
> > it out - "assuming" they've followed the usual methods there's only a
> > few ways they could be doing this.
> >
> > Regards,
> >
> > David
> >  
>


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Julius Davies
Good work!  Integer count as a string!  Wow.  Thanks for figuring this
out.  I was pretty puzzled.

yours,

Julius


On 2/24/07, David Hook <[hidden email]> wrote:

>
> Cool! (Yes, that saved a bit of head scratching). Minor suggestion for
> anyone using this, with getBytes() it's probably a good idea to specify
> "US-ASCII" as well.
>
> I'll add a generator for this to the lightweight API.
>
> Regards,
>
> David
>
> On Sat, 2007-02-24 at 18:27 +1100, Peter Dettman wrote:
> > The Mono project has the algorithm - see
> > http://svn.myrealbox.com/viewcvs/trunk/mcs/class/corlib/System.Security.Cryptography/PasswordDeriveBytes.cs?view=markup
> >
> > Briefly, each 20 bytes (for SHA1) is generated according to the PBKDF1
> > algorithm, except for the final iteration:
> >
> > - For first 20 bytes, last iteration is as normal.
> >
> > - For subsequent 20 byte increments, the last iteration additionally
> > (before the normal update) updates the digest using the 'count' of
> > number of buffers so far (actually the bytes of the string
> > representation) i.e.:
> >             byte[] prefix = Integer.toString(count).getBytes();
> >             digest.update(prefix, 0, prefix.length);
> >
> > - The algorithm is limited to 1000 * 20 bytes.
> >
> > Also, note that subsequent calls to PasswordDeriveBytes.GetBytes
> > generate further bytes in the 'stream', rather than starting the
> > algorithm from scratch each time.
> >
> > Oh, and Dave, I bet that wasn't in your list of guesses of the way they
> > could be doing this :o).
> >
> > Cheers,
> > Pete.
> >
> >
> > P.S. I include my simplistic Java implementation of this algorithm below
> > (for generateDerivedParameters(int) only). This implementation seems to
> > produce the same output as the .NET class.
> >
> >
> > import org.bouncycastle.crypto.CipherParameters;
> > import org.bouncycastle.crypto.Digest;
> > import org.bouncycastle.crypto.digests.SHA1Digest;
> > import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
> > import org.bouncycastle.crypto.params.KeyParameter;
> > import org.bouncycastle.util.encoders.Hex;
> >
> >
> > public class PKCS5Test
> > {
> >     /**
> >      * @param args
> >      */
> >     public static void main(String[] args) throws Exception
> >     {
> >         byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
> > 13, 14, 15 };
> >         byte[] salt =
> > PKCS5S1ParametersGenerator.PKCS5PasswordToBytes("MyTesting".toCharArray());
> >
> >         PKCS5S1ParametersGenerator generator = new
> > PasswordDeriveBytes(new SHA1Digest());
> >         generator.init(password, salt, 100);
> >
> >         byte[] key = ((KeyParameter)
> > generator.generateDerivedParameters(512)).getKey();
> >         System.out.println( "64 " + new
> > String(Hex.encode(key)).toUpperCase() );
> >     }
> >
> >     static class PasswordDeriveBytes extends PKCS5S1ParametersGenerator
> >     {
> >         private final Digest d;
> >
> >         private byte[] output = null;
> >
> >         public PasswordDeriveBytes(Digest d)
> >         {
> >             super(d);
> >
> >             this.d = d;
> >         }
> >
> >         public CipherParameters generateDerivedParameters(
> >             int keySize)
> >         {
> >             keySize = keySize / 8;
> >
> >             byte[] result = new byte[keySize];
> >             int done = 0;
> >             int count = 0;
> >             byte[] b = null;
> >
> >             while (done < result.length)
> >             {
> >                 if (b == null)
> >                 {
> >                     b = generateInitialKey();
> >                 }
> >                 else if (++count < 1000)
> >                 {
> >                     b = generateExtendedKey(++count);
> >                 }
> >                 else
> >                 {
> >                     throw new RuntimeException("Exceeded limit");
> >                 }
> >
> >                 int use = Math.min(b.length, result.length - done);
> >                 System.arraycopy(b, 0, result, done, use);
> >                 done += use;
> >             }
> >
> >             return new KeyParameter(result);
> >         }
> >
> >         private byte[] generateOutput()
> >         {
> >             byte[] digestBytes = new byte[d.getDigestSize()];
> >
> >             d.update(password, 0, password.length);
> >             d.update(salt, 0, salt.length);
> >             d.doFinal(digestBytes, 0);
> >
> >             for (int i = 1; i < (iterationCount - 1); i++)
> >             {
> >                 d.update(digestBytes, 0, digestBytes.length);
> >                 d.doFinal(digestBytes, 0);
> >             }
> >
> >             return digestBytes;
> >         }
> >
> >         private byte[] generateInitialKey()
> >         {
> >             output = generateOutput();
> >             d.update(output, 0, output.length);
> >
> >             byte[] digestBytes = new byte[d.getDigestSize()];
> >             d.doFinal(digestBytes, 0);
> >             return digestBytes;
> >         }
> >
> >         private byte[] generateExtendedKey(int count)
> >         {
> >             byte[] prefix = Integer.toString(count).getBytes();
> >             d.update(prefix, 0, prefix.length);
> >             d.update(output, 0, output.length);
> >
> >             byte[] digestBytes = new byte[d.getDigestSize()];
> >             d.doFinal(digestBytes, 0);
> >
> >             //System.err.println( "X: " + new
> > String(Hex.encode(digestBytes)).toUpperCase() );
> >             return digestBytes;
> >         }
> >     }
> > }
> >
> >
> > David Hook wrote:
> > > If you can send me some samples of longer keys I might be able to work
> > > it out - "assuming" they've followed the usual methods there's only a
> > > few ways they could be doing this.
> > >
> > > Regards,
> > >
> > > David
> > >
> >
>
>
>


--
yours,

Julius Davies
416-652-0183
http://juliusdavies.ca/

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Ahmed Ashour-2
In reply to this post by Peter Dettman
Dear Peter,

Thanks a lot for your input, code seems to be very close, however, the
results do not exactly match (after the first 20 bytes).

.NET result:
04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF89092289946D3662B3196860A8041FCD7E8DA4

Implementation provided:
04DD9D139DCB9DE889946D3662B319682159FF9C60A8041FCD7E8DA48D1C276CD686646C94EF827D7F4C9BBA4E6193ED

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Peter Dettman
Uh, sorry, I messed it up in my last minute refactoring...

At line 55, it should be:
                else if (++count < 1000)
                {
                    b = generateExtendedKey(count);
                }

Also,

My implementation then produces:
64
04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922655D8DD89AE1CAAC60A8041FCD7E8DA48D1C276CD686646C94EF827D78711AED


This .NET program gives the same result:
        public static void Main(
            string[] args)
        {
            byte[] password = { 00, 01, 02, 03, 04, 05, 06, 07, 08,
                09, 10, 11, 12, 13, 14, 15 };
            byte[] salt = Encoding.ASCII.GetBytes("MyTesting");
            PasswordDeriveBytes pdb = new
PasswordDeriveBytes(Encoding.ASCII.GetString(password), salt);
            byte[] key = pdb.GetBytes(64);
            Console.WriteLine("PasswordDeriveBytes: Hash=" +
                pdb.HashName + ", iterations=" + pdb.IterationCount);
            Console.WriteLine( "Key " +
Encoding.ASCII.GetString(Hex.Encode(key)) );
        }

64
04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922655D8DD89AE1CAAC60A8041FCD7E8DA48D1C276CD686646C94EF827D78711AED

I am not sure how you got your .NET result below, which is different
from mine after 32 bytes...

Pete.

Ahmed Ashour wrote:

> Dear Peter,
>
> Thanks a lot for your input, code seems to be very close, however, the
> results do not exactly match (after the first 20 bytes).
>
> .NET result:
> 04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF89092289946D3662B3196860A8041FCD7E8DA4
>
>
> Implementation provided:
> 04DD9D139DCB9DE889946D3662B319682159FF9C60A8041FCD7E8DA48D1C276CD686646C94EF827D7F4C9BBA4E6193ED
>
>


smime.p7s (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Peter Dettman
I see now that yours is the result of calling GetBytes(32), then
GetBytes(16), which gives a different result than just calling GetBytes(48).

I guess I need to look at this a bit closer.

Peter Dettman wrote:

>
> 64
> 04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922655D8DD89AE1CAAC60A8041FCD7E8DA48D1C276CD686646C94EF827D78711AED
>
>
> I am not sure how you got your .NET result below, which is different
> from mine after 32 bytes...
>
> Pete.
>
> Ahmed Ashour wrote:
>> Dear Peter,
>>
>> Thanks a lot for your input, code seems to be very close, however, the
>> results do not exactly match (after the first 20 bytes).
>>
>> .NET result:
>> 04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF89092289946D3662B3196860A8041FCD7E8DA4
>>
>>
>> Implementation provided:
>> 04DD9D139DCB9DE889946D3662B319682159FF9C60A8041FCD7E8DA48D1C276CD686646C94EF827D7F4C9BBA4E6193ED
>>
>>
>


smime.p7s (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Ahmed Ashour-2
In reply to this post by Peter Dettman
Dear Peter,

Everything is fine, my 48 are the first ones of your 64.

I tested the proposed implementation for 32 *100 bytes, and it works.

Thank you so much.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Ahmed Ashour-2
Aha, I see your point.

Interestingly, using .NET: the results are different when calling 48
or calling 32 followed by 16:

.NET GetBytes( 32 +16 ):
04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922655D8DD89AE1CAAC60A8041FCD7E8DA4


.NET GetBytes( 32 )
04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922
Followed by GetBytes( 16 )
89946D3662B3196860A8041FCD7E8DA4

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Peter Dettman
Yeah, it's different.

I have just tried this under Mono, and they give the same bytes as my
attempt (well, I based my code on theirs!) regardless of whether it's
one call or two. So, I am not sure if this is a bug in MS.NET or what.

If we add an implementation to BC we probably wouldn't support multiple
calls to generateDerivedParameters anyway, so maybe you should just make
sure to only call GetBytes once in your ".NET code and split it up yourself.

Cheers,
Pete.

Ahmed Ashour wrote:

> Aha, I see your point.
>
> Interestingly, using .NET: the results are different when calling 48
> or calling 32 followed by 16:
>
> .NET GetBytes( 32 +16 ):
> 04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922655D8DD89AE1CAAC60A8041FCD7E8DA4
>
>
>
> .NET GetBytes( 32 )
> 04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922
> Followed by GetBytes( 16 )
> 89946D3662B3196860A8041FCD7E8DA4
>


smime.p7s (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

David Hook-4

Yes, it's hard to think of it as a feature - it seems very odd that the
16 byte generation has bytes 8-16 and bytes 40-48 of the 48 byte
generation. It's possible it's just a coincidence but the odds of such a
good match are rather large. I don't think it's really something we'd
like to emulate.

Regards,

David

On Sun, 2007-02-25 at 04:02 +1100, Peter Dettman wrote:

> Yeah, it's different.
>
> I have just tried this under Mono, and they give the same bytes as my
> attempt (well, I based my code on theirs!) regardless of whether it's
> one call or two. So, I am not sure if this is a bug in MS.NET or what.
>
> If we add an implementation to BC we probably wouldn't support multiple
> calls to generateDerivedParameters anyway, so maybe you should just make
> sure to only call GetBytes once in your ".NET code and split it up yourself.
>
> Cheers,
> Pete.
>
> Ahmed Ashour wrote:
> > Aha, I see your point.
> >
> > Interestingly, using .NET: the results are different when calling 48
> > or calling 32 followed by 16:
> >
> > .NET GetBytes( 32 +16 ):
> > 04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922655D8DD89AE1CAAC60A8041FCD7E8DA4
> >
> >
> >
> > .NET GetBytes( 32 )
> > 04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922
> > Followed by GetBytes( 16 )
> > 89946D3662B3196860A8041FCD7E8DA4
> >
>


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Peter Dettman
Well, now that I go looking for bug reports, I find that Mono has already been here:

http://bugzilla.ximian.com/show_bug.cgi?id=69036


David Hook wrote:
Yes, it's hard to think of it as a feature - it seems very odd that the
16 byte generation has bytes 8-16 and bytes 40-48 of the 48 byte
generation. It's possible it's just a coincidence but the odds of such a
good match are rather large. I don't think it's really something we'd
like to emulate.

Regards,

David

On Sun, 2007-02-25 at 04:02 +1100, Peter Dettman wrote:
  
Yeah, it's different.

I have just tried this under Mono, and they give the same bytes as my 
attempt (well, I based my code on theirs!) regardless of whether it's 
one call or two. So, I am not sure if this is a bug in MS.NET or what.

If we add an implementation to BC we probably wouldn't support multiple 
calls to generateDerivedParameters anyway, so maybe you should just make 
sure to only call GetBytes once in your ".NET code and split it up yourself.

Cheers,
Pete.

Ahmed Ashour wrote:
    
Aha, I see your point.

Interestingly, using .NET: the results are different when calling 48
or calling 32 followed by 16:

.NET GetBytes( 32 +16 ):
04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922655D8DD89AE1CAAC60A8041FCD7E8DA4 



.NET GetBytes( 32 )
04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922
Followed by GetBytes( 16 )
89946D3662B3196860A8041FCD7E8DA4

      


  


smime.p7s (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

David Hook-4
In reply to this post by Ahmed Ashour-2

Just a further one on this, the following link appeared on the reference
Peter posted yesterday. According to this:

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93955

the problem is supposed to have been fixed.

Julius, Ahmed - which versions of .NET are you seeing this on? If it
really hasn't been fixed the issue should be reopened with Microsoft, I
don't think they'll be very happy when they appreciate what the
implications are and I'm sure they'd rather fix it.

Regards,

David



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Ahmed Ashour-2
Dear David,

I am using Visual Studio Version 8.0.50727.42 (RTM.050727-4200), with
.NET framework Version 2.0.50727.

Visual Studio doesn't recognize the installed .NET framework 3.0!

On 2/26/07, David Hook <[hidden email]> wrote:

>
> Just a further one on this, the following link appeared on the reference
> Peter posted yesterday. According to this:
>
> http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93955
>
> the problem is supposed to have been fixed.
>
> Julius, Ahmed - which versions of .NET are you seeing this on? If it
> really hasn't been fixed the issue should be reopened with Microsoft, I
> don't think they'll be very happy when they appreciate what the
> implications are and I'm sure they'd rather fix it.
>
> Regards,
>
> David
>
>
>
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

Ahmed Ashour-2
Dear All,

Just a hint, the below version is the Visual Studio 2005 release, and
even after upgrading to VS2005 SP1, the problem persists.

Although the mentioned bugs has been reported as fixed in VS beta, the
issue still exists.

I am trying to see if there is any Service Pack for .NET framework,
and see, and if it is not resolved, I will have to notify Microsoft.

Many thanks for your priceless help.

On 2/26/07, Ahmed Ashour <[hidden email]> wrote:

> Dear David,
>
> I am using Visual Studio Version 8.0.50727.42 (RTM.050727-4200), with
> .NET framework Version 2.0.50727.
>
> Visual Studio doesn't recognize the installed .NET framework 3.0!
>
> On 2/26/07, David Hook <[hidden email]> wrote:
> >
> > Just a further one on this, the following link appeared on the reference
> > Peter posted yesterday. According to this:
> >
> > http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93955
> >
> > the problem is supposed to have been fixed.
> >
> > Julius, Ahmed - which versions of .NET are you seeing this on? If it
> > really hasn't been fixed the issue should be reopened with Microsoft, I
> > don't think they'll be very happy when they appreciate what the
> > implications are and I'm sure they'd rather fix it.
> >
> > Regards,
> >
> > David
> >
> >
> >
> >
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

darshkemo
In reply to this post by Peter Dettman
Hi
I am moving from .net to java
with the same codes/problems wrote here
I have 16byte key and 16 byte iv
my only problem is that the .net code calls pdb(PasswordDerivedBytes) two times, not one!
one for the key and another for iv
so I face the problem mentioned (calling pdb.getBytes(16) two times is different than calling it one time(32)) so the java key generated is different in the iv bytes :(
If the .net calls pdb.getBytes(32), there won't be no problem.
any one has suggestion?
Thanks
Peter Dettman wrote
Yeah, it's different.

I have just tried this under Mono, and they give the same bytes as my
attempt (well, I based my code on theirs!) regardless of whether it's
one call or two. So, I am not sure if this is a bug in MS.NET or what.

If we add an implementation to BC we probably wouldn't support multiple
calls to generateDerivedParameters anyway, so maybe you should just make
sure to only call GetBytes once in your ".NET code and split it up yourself.

Cheers,
Pete.

Ahmed Ashour wrote:
> Aha, I see your point.
>
> Interestingly, using .NET: the results are different when calling 48
> or calling 32 followed by 16:
>
> .NET GetBytes( 32 +16 ):
> 04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922655D8DD89AE1CAAC60A8041FCD7E8DA4
>
>
>
> .NET GetBytes( 32 )
> 04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922
> Followed by GetBytes( 16 )
> 89946D3662B3196860A8041FCD7E8DA4
>


 
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: .NET PasswordDeriveBytes

ramireddy
This post has NOT been accepted by the mailing list yet.
In reply to this post by Ahmed Ashour-2
Dear All,

I have .net code which is having to convert msisdn string  into encryption format .I need to convert same algorithm into  java .And i am new to .net,please provide the suggestion to make the code into java.i have tried to convert into java but i am getting different output.if possible kindly  provide the code into java.


Class Defining the Encryption and Decryption Class
-----------------------------------------------------------------
public static class Cryptography
    {
        #region Settings

        private static int _iterations = 2;
        private static int _keySize = 256;

        private static string _hash = "SHA1";
        private static string _salt = "aselrias38490a32";
        private static string _vector = "8947az34awl34kjq";
       
       

        #endregion

        public static string Encrypt(string value, string password)
        {
            return Encrypt<AesManaged>(value, password);
        }
        public static string Encrypt<T>(string value, string password)
                where T : SymmetricAlgorithm, new()
        {
            byte[] vectorBytes = ASCIIEncoding.ASCII.GetBytes(_vector);
            byte[] saltBytes = ASCIIEncoding.ASCII.GetBytes(_salt);
            byte[] valueBytes = UTF8Encoding.UTF8.GetBytes(value);

            byte[] encrypted;
            using (T cipher = new T())
            {
                PasswordDeriveBytes _passwordBytes =
                    new PasswordDeriveBytes(password, saltBytes, _hash,
_iterations);
                byte[] keyBytes = _passwordBytes.GetBytes(_keySize / 8);

                cipher.Mode = CipherMode.CBC;

                using (ICryptoTransform encryptor =
cipher.CreateEncryptor(keyBytes, vectorBytes))
                {
                    using (MemoryStream to = new MemoryStream())
                    {
                        using (CryptoStream writer = new CryptoStream(to,
encryptor, CryptoStreamMode.Write))
                        {
                            writer.Write(valueBytes, 0, valueBytes.Length);
                            writer.FlushFinalBlock();
                            encrypted = to.ToArray();
                        }
                    }
                }
                cipher.Clear();
            }
            return Convert.ToBase64String(encrypted);
        }

        public static string Decrypt(string value, string password)
        {
            return Decrypt<AesManaged>(value, password);
        }
        public static string Decrypt<T>(string value, string password) where
T : SymmetricAlgorithm, new()
        {
            byte[] vectorBytes = ASCIIEncoding.ASCII.GetBytes(_vector);
            byte[] saltBytes = ASCIIEncoding.ASCII.GetBytes(_salt);
            byte[] valueBytes = Convert.FromBase64String(value);

            byte[] decrypted;
            int decryptedByteCount = 0;

            using (T cipher = new T())
            {
                PasswordDeriveBytes _passwordBytes = new
PasswordDeriveBytes(password, saltBytes, _hash, _iterations);
                byte[] keyBytes = _passwordBytes.GetBytes(_keySize / 8);

                cipher.Mode = CipherMode.CBC;

                try
                {
                    using (ICryptoTransform decryptor =
cipher.CreateDecryptor(keyBytes, vectorBytes))
                    {
                        using (MemoryStream from = new
MemoryStream(valueBytes))
                        {
                            using (CryptoStream reader = new
CryptoStream(from, decryptor, CryptoStreamMode.Read))
                            {
                                decrypted = new byte[valueBytes.Length];
                                decryptedByteCount = reader.Read(decrypted,
0, decrypted.Length);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    return String.Empty;
                }

                cipher.Clear();
            }
            return Encoding.UTF8.GetString(decrypted, 0,
decryptedByteCount);
        }

    }


Testing Encryption and Decryption Functions
--------------------------------------------------------
string encrypted = encryption.Cryptography.Encrypt("9849959978",
"msme@123");
string decrypted = encryption.Cryptography.Decrypt(encrypted, "msme@123");



Ahmed Ashour-2 wrote
Dear All,

Using BC for J2ME, how to have the same behaviour as .NET
PasswordDeriveBytes?  As you see in the below code, the results are
different, notice that IterationCount is 100 by default.

In PasswordDeriveBytes docs, "This class uses an extension of the
PBKDF1 algorithm defined in the PKCS#5 v2.0 standard to derive bytes
suitable for use as key material from a password. The standard is
documented in IETF RRC 2898."


------------------------------------------------------------------------------------
            byte[] password = { 00, 01, 02, 03, 04, 05, 06, 07, 08,
09, 10, 11, 12, 13, 14, 15 };
            byte[] salt = System.Text.ASCIIEncoding.ASCII.GetBytes("MyTesting");
            PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, salt);
            byte[] key = pdb.GetBytes(32);
            byte[] iv = pdb.GetBytes(16);
            System.Console.WriteLine("PasswordDeriveBytes: Hash=" +
pdb.HashName + ", iterations=" + pdb.IterationCount);
            System.Console.WriteLine( "Key " + toHexString( key ) );
            System.Console.WriteLine( "IV " + toHexString( iv ) );
------------------------------------------------------------------------------------
                byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

                byte[] salt = PKCS5S2ParametersGenerator.PKCS5PasswordToBytes(
"MyTesting".toCharArray() );

                KDF1BytesGenerator generator = new KDF1BytesGenerator( new SHA1Digest() );
                generator.init( new KDFParameters( password, salt ) );

                byte[] key = new byte[32];
                generator.generateBytes( key, 0, key.length );
                System.out.println( "32 " + new String( Hex.encode( key ) ).toUpperCase() );
               
                byte[] iv = new byte[16];
                generator.generateBytes( iv, 0, iv.length );
                System.out.println( "16 " + new String( Hex.encode( iv ) ).toUpperCase() );
------------------------------------------------------------------------------------
Loading...