Simple encryption/decryption

Discussion in 'Java' started by angelochen960@gmail.com, Mar 23, 2009.

  1. Guest

    I'm looking for a simple solution: a way to encrypt a string into a
    alphanumeric string, and can be decrypted back to its original form,
    using a string as the key, say 'password123', any idea how to achieve
    this? Thanks.
     
    , Mar 23, 2009
    #1
    1. Advertising

  2. Mark Space Guest

    wrote:

    > I'm looking for a simple solution: a way to encrypt a string into a
    > alphanumeric string, and can be decrypted back to its original form,
    > using a string as the key, say 'password123', any idea how to achieve
    > this? Thanks.



    Here's a little something to get you started. I'll see if I can muddle
    through an example soonish.

    <http://java.sun.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html>
     
    Mark Space, Mar 23, 2009
    #2
    1. Advertising

  3. wrote:
    > I'm looking for a simple solution: a way to encrypt a string into a
    > alphanumeric string, and can be decrypted back to its original form,
    > using a string as the key, say 'password123', any idea how to achieve
    > this? Thanks.


    Well, there's always ROT-13. For extra security, you might want to
    perform it twice. :p

    If you're trying to store passwords, it's generally advisable to store a
    hash of the password. For example, my Linux password is stored as the
    following:
    $1$exPy4JWs$Fp5p5vjY6b0P0m1HzSTxu.

    The $1 indicates that this is an MD5-encrypted password
    The $exPy4JWs$ indicates that exPy4JWs is the salt
    The rest is the actual hash, in base64-form.

    P.S., if you could tell me what the password is, please do! I've
    forgotten what I made it...
    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
     
    Joshua Cranmer, Mar 23, 2009
    #3
  4. Mark Space Guest

    wrote:

    > I'm looking for a simple solution: a way to encrypt a string into a
    > alphanumeric string, and can be decrypted back to its original form,
    > using a string as the key, say 'password123', any idea how to achieve
    > this? Thanks.



    I'm not seeing a good answer to this. In particular, the
    SecretKeyFactory.getInstance( "ARCFOUR" ) method returns an error. I
    don't see a simple way to use RC4 without this call succeeding. Anyone
    got a solution?

    Anyway, to the OP, check out the code below. It will at least get you
    going. Sorry for the lack of Javadoc comments, I just had this laying
    around on the hard drive. You can compare this code to the description
    of RC4 at Wikipedia. It's the exact same algorithm. Note the test vectors.

    <http://en.wikipedia.org/wiki/RC4>


    package local;

    /**

    COPYRIGHT 2009 Brenden Towey

    This code is donated to the public domain but is unsupported and has no
    warranty whatsoever. Use at your own risk.

    *
    * @author Brenden
    */
    public class Rc4
    {
    private byte[] state = new byte[256];
    int x, y;

    public Rc4( byte[] key )
    {
    // if( key.length<5||key.length>16 )
    // {
    // throw new IllegalArgumentException( "Key: "+key+
    // " must be between 40 and 128 bits. (key length is "+
    // key.length+".)" );
    // }
    for( int i = 0; i < state.length; i++ ) {
    state = (byte) i;
    }
    for( int i = 0; i < state.length; i++ ) {
    x = (x + key[i % key.length] + state) & 0xFF;
    byte swap = state;
    state = state[x];
    state[x] = swap;
    }
    x = 0;
    }

    public byte[] crypt( byte[] input )
    {
    byte[] output = new byte[input.length];
    for( int i = 0; i < input.length; i++ ) {
    x = (x + 1) % 256;
    y = (state[x] + y) & 0xFF;
    byte swap = state[x];
    state[x] = state[y];
    state[y] = swap;
    byte r = state[(state[x] + state[y]) & 0xFF];
    output = (byte) (input ^ r);
    }
    return output;
    }

    public static void main( final String... args )
    {
    String[][] testVectors = {{"Key", "Plaintext"},
    {"Wiki", "pedia"}, {"Secret", "Attack at dawn"}
    };
    for( String[] s : testVectors ) {
    System.out.printf( "RC4( \"%s\", \"%s\" ) == ", s[0], s[1] );
    System.out.println( hexString( new Rc4( s[0].getBytes()
    ).crypt( s[1].
    getBytes() ) ) );
    }
    }

    private static String hexString( byte[] bytes )
    {
    StringBuilder sb = new StringBuilder( bytes.length *2 );
    for( int i = 0; i < bytes.length; i++ ) {
    sb.append( String.format( "%02X", bytes ));
    }
    return sb.toString();
    // return local.utils.ArrayUtils.toFormattedString( "%02X",
    //bytes, null );
    }
    }
     
    Mark Space, Mar 23, 2009
    #4
  5. Roedy Green Guest

    On Mon, 23 Mar 2009 07:50:59 -0700 (PDT), ""
    <> wrote, quoted or indirectly quoted someone
    who said :

    >I'm looking for a simple solution: a way to encrypt a string into a
    >alphanumeric string, and can be decrypted back to its original form,
    >using a string as the key, say 'password123', any idea how to achieve
    >this? Thanks.


    Sample code for a JCE solution is posted at
    http://mindprod.com/jgloss/aes.html
    Follow the links for others.


    Sample code for a non-JCE solution, using public encryption is posted
    at http://mindprod.com/jgloss/products1.html#TRANSPORTER
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    "Nature provides a free lunch, but only if we control our appetites."
    ~ William Ruckelshaus, America’s first head of the EPA
     
    Roedy Green, Mar 23, 2009
    #5
  6. rossum wrote:
    > IIRC, Base-64 is not part of standard Java, though there is an
    > undocumented version in sun.misc. There are a lot of implementations
    > floating about on the internet; I use Bouncy Castle, which has Base-64
    > as part of their general crypto package.


    Base64 is part of the Java EE spec. It is under the mail stuff.

    Arne
     
    Arne Vajhøj, Mar 23, 2009
    #6
  7. Lew Guest

    rossum wrote:
    >> IIRC,


    You do not.

    >> Base-64 is not part of standard Java, though there is an
    >> undocumented version in sun.misc. There are a lot of implementations


    Sun warns us not to use the sun.misc packages.

    >> floating about on the internet; I use Bouncy Castle, which has Base-64
    >> as part of their general crypto package.


    Apache commons-codec has it also. Besides, as
    Arne Vajhøj wrote:
    > Base64 is part of the Java EE spec. It is under the mail stuff.


    <http://java.sun.com/javaee/5/docs/api/javax/mail/internet/MimeUtility.html#decode(java.io.InputStream,%20java.lang.String)>
    <http://java.sun.com/javaee/5/docs/api/javax/mail/internet/MimeUtility.html#encode(java.io_OutputStream,%20java.lang.String)>

    --
    Lew
     
    Lew, Mar 23, 2009
    #7
  8. Lew wrote:
    > rossum wrote:
    >>> Base-64 is not part of standard Java, though there is an
    >>> undocumented version in sun.misc. There are a lot of implementations


    >>> floating about on the internet; I use Bouncy Castle, which has Base-64
    >>> as part of their general crypto package.

    >
    > Apache commons-codec has it also. Besides, as


    > Arne Vajhøj wrote:
    >> Base64 is part of the Java EE spec. It is under the mail stuff.

    >
    > <http://java.sun.com/javaee/5/docs/api/javax/mail/internet/MimeUtility.html#decode(java.io.InputStream,%20java.lang.String)>
    > <http://java.sun.com/javaee/5/docs/api/javax/mail/internet/MimeUtility.html#encode(java.io_OutputStream,%20java.lang.String)>


    The code is simple:

    public static String b64encode(byte[] b) throws MessagingException,
    IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    OutputStream b64os = MimeUtility.encode(baos, "base64");
    b64os.write(b);
    b64os.close();
    return new String(baos.toByteArray());
    }
    public static byte[] b64decode(String s) throws
    MessagingException, IOException {
    ByteArrayInputStream bais = new ByteArrayInputStream(s.getBytes());
    InputStream b64is = MimeUtility.decode(bais, "Base64");
    byte[] tmp = new byte[s.length()];
    int n = b64is.read(tmp);
    byte[] res = new byte[n];
    System.arraycopy(tmp, 0, res, 0, n);
    return res;
    }

    and if it is in Java EE context the classes are there - if it is in
    pure Java SE context then getting JavaMail and put that jar in classpath
    is enough.

    Arne
     
    Arne Vajhøj, Mar 23, 2009
    #8
  9. Arne Vajhøj Guest

    Mark Space wrote:
    > wrote:
    >> I'm looking for a simple solution: a way to encrypt a string into a
    >> alphanumeric string, and can be decrypted back to its original form,
    >> using a string as the key, say 'password123', any idea how to achieve
    >> this? Thanks.

    >
    > I'm not seeing a good answer to this. In particular, the
    > SecretKeyFactory.getInstance( "ARCFOUR" ) method returns an error. I
    > don't see a simple way to use RC4 without this call succeeding. Anyone
    > got a solution?


    private Cipher rc4;
    private SecretKey rc4key;
    public RC4(String key) {
    try {
    rc4 = Cipher.getInstance("RC4");
    rc4key = new SecretKeySpec(key.getBytes(), "RC4");
    } catch(Exception e) {
    e.printStackTrace();
    }
    }

    works fine for me.

    Arne
     
    Arne Vajhøj, Mar 24, 2009
    #9
  10. Roedy Green Guest

    On Mon, 23 Mar 2009 21:17:41 +0000, rossum <>
    wrote, quoted or indirectly quoted someone who said :

    >Others have talked about encryption - RC4 etc. Using a cypher will
    >produce an array, or stream, of bytes. In order to get those bytes
    >into alphanumeric form you will need to use Base-64 (or similar) to
    >code those bytes as alphanumeric characters.


    see http://mindprod.com/jgloss/base64.html
    and
    http://mindprod.com/jgloss/armouring.html

    The Transporter code I pointed you to does armouring using Base64
    ..
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    "Nature provides a free lunch, but only if we control our appetites."
    ~ William Ruckelshaus, America’s first head of the EPA
     
    Roedy Green, Mar 24, 2009
    #10
  11. Mark Space Guest

    Arne Vajhøj wrote:

    > Mark Space wrote:
    >>
    >> I'm not seeing a good answer to this. In particular, the
    >> SecretKeyFactory.getInstance( "ARCFOUR" ) method returns an error. I
    >> don't see a simple way to use RC4 without this call succeeding.
    >> Anyone got a solution?

    >
    > private Cipher rc4;
    > private SecretKey rc4key;
    > public RC4(String key) {
    > try {
    > rc4 = Cipher.getInstance("RC4");
    > rc4key = new SecretKeySpec(key.getBytes(), "RC4");
    > } catch(Exception e) {
    > e.printStackTrace();
    > }
    > }
    >
    > works fine for me.



    Thanks for that, I'll play around with it. I read the docs and thought
    I was supposed to use a SecretKeyFactory. The SecretKeySpec class
    looked like something else (a "specification" for the key).

    Just for reference, the following fails on line 34 (marked):


    public class Encryption {

    Cipher c;
    public Encryption( String password )
    throws NoSuchAlgorithmException,
    NoSuchPaddingException,
    InvalidKeySpecException,
    InvalidKeyException
    {
    c = Cipher.getInstance( "RC4" );
    char[] passChars = new char[password.length()];
    password.getChars( 0, passChars.length, passChars, 0 );
    // line 34 below
    SecretKeyFactory skf = SecretKeyFactory.getInstance( "ARCFOUR" );
    SecretKey sk = skf.generateSecret( new PBEKeySpec( passChars ) );
    c.init( Cipher.ENCRYPT_MODE, sk );
    }

    public static void main ( String... args )
    throws Exception
    {
    System.out.println( new Encryption("password1234") );
    }
    }
     
    Mark Space, Mar 24, 2009
    #11
  12. Mark Space Guest

    Seems to work:

    package fubar;

    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.spec.InvalidKeySpecException;
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;

    public class Encryption {

    Cipher rc4;
    SecretKey rc4Key;

    public Encryption( String password )
    throws NoSuchAlgorithmException,
    NoSuchPaddingException,
    InvalidKeySpecException,
    InvalidKeyException
    {
    rc4 = Cipher.getInstance( "RC4" );
    rc4Key = new SecretKeySpec( password.getBytes(), "RC4" );
    rc4.init( Cipher.ENCRYPT_MODE, rc4Key );
    }

    public byte[] crypt( byte[] input )
    throws IllegalBlockSizeException,
    BadPaddingException
    {
    return rc4.doFinal( input );
    }

    public static void main ( String... args )
    throws Exception
    {
    // RC4 test vectors from Wikipedia
    // Only "Secret" is long enough to supply the required
    // 40 bits.

    String [][] testVectors = { { "Secret", "Attack at dawn"} };

    for( String[] s : testVectors ) {
    Encryption encryption = new Encryption( s[0] );
    System.out.println( hexBytes( encryption.crypt(
    s[1].getBytes() ) ) );
    }
    }

    private static String hexBytes( byte[] bytes ) {
    StringBuilder sb = new StringBuilder( bytes.length *2 );
    for( int i = 0; i < bytes.length; i++ ) {
    sb.append( String.format( "%02X", bytes ) );
    }
    return sb.toString();
    }

    }
     
    Mark Space, Mar 24, 2009
    #12
  13. Arne Vajhøj Guest

    Mark Space wrote:
    > Arne Vajhøj wrote:
    >> Mark Space wrote:
    >>>
    >>> I'm not seeing a good answer to this. In particular, the
    >>> SecretKeyFactory.getInstance( "ARCFOUR" ) method returns an error. I
    >>> don't see a simple way to use RC4 without this call succeeding.
    >>> Anyone got a solution?

    >>
    >> private Cipher rc4;
    >> private SecretKey rc4key;
    >> public RC4(String key) {
    >> try {
    >> rc4 = Cipher.getInstance("RC4");
    >> rc4key = new SecretKeySpec(key.getBytes(), "RC4");
    >> } catch(Exception e) {
    >> e.printStackTrace();
    >> }
    >> }
    >>
    >> works fine for me.

    >
    > Thanks for that, I'll play around with it. I read the docs and thought
    > I was supposed to use a SecretKeyFactory. The SecretKeySpec class
    > looked like something else (a "specification" for the key).


    If the constructor works, then I would have expected the factory to
    work as well.

    But apparently not.

    Arne
     
    Arne Vajhøj, Mar 24, 2009
    #13
  14. Angelo Chen Guest

    On Mar 24, 2:13 am, Mark Space <> wrote:
    > wrote:
    > > I'm looking for a simple solution:  a way to encrypt a string into a
    > > alphanumeric string, and can be decrypted back to its original form,
    > > using a string as the key, say 'password123', any idea how to achieve
    > > this? Thanks.

    >
    > I'm not seeing a good answer to this.  In particular, the
    > SecretKeyFactory.getInstance( "ARCFOUR" ) method returns an error.  I
    > don't see a simple way to use RC4 without this call succeeding.  Anyone
    > got a solution?
    >
    > Anyway, to the OP, check out the code below.  It will at least get you
    > going.  Sorry for the lack of Javadoc comments, I just had this laying
    > around on the hard drive.  You can compare this code to the description
    > of RC4 at Wikipedia.  It's the exact same algorithm.  Note the test vectors.
    >
    > <http://en.wikipedia.org/wiki/RC4>
    >
    > package local;
    >
    > /**
    >
    > COPYRIGHT 2009 Brenden Towey
    >
    > This code is donated to the public domain but is unsupported and has no
    > warranty whatsoever. Use at your own risk.
    >
    >   *
    >   * @author Brenden
    >   */
    > public class Rc4
    > {
    >      private byte[] state = new byte[256];
    >      int x, y;
    >
    >      public Rc4( byte[] key )
    >      {
    > //        if( key.length<5||key.length>16 )
    > //        {
    > //            throw new IllegalArgumentException( "Key: "+key+
    > //             " must be between 40 and 128 bits. (key length is "+
    > //               key.length+".)" );
    > //        }
    >          for( int i = 0; i < state.length; i++ ) {
    >              state = (byte) i;
    >          }
    >          for( int i = 0; i < state.length; i++ ) {
    >              x = (x + key[i % key.length] + state) & 0xFF;
    >              byte swap = state;
    >              state = state[x];
    >              state[x] = swap;
    >          }
    >          x = 0;
    >      }
    >
    >      public byte[] crypt( byte[] input )
    >      {
    >          byte[] output = new byte[input.length];
    >          for( int i = 0; i < input.length; i++ ) {
    >              x = (x + 1) % 256;
    >              y = (state[x] + y) & 0xFF;
    >              byte swap = state[x];
    >              state[x] = state[y];
    >              state[y] = swap;
    >              byte r = state[(state[x] + state[y]) & 0xFF];
    >              output = (byte) (input ^ r);
    >          }
    >          return output;
    >      }
    >
    >      public static void main( final String... args )
    >      {
    >          String[][] testVectors = {{"Key", "Plaintext"},
    >              {"Wiki", "pedia"}, {"Secret", "Attack at dawn"}
    >          };
    >          for( String[] s : testVectors ) {
    >              System.out.printf( "RC4( \"%s\", \"%s\" ) == ", s[0], s[1] );
    >              System.out.println( hexString( new Rc4( s[0].getBytes()
    > ).crypt( s[1].
    >                      getBytes() ) ) );
    >          }
    >      }
    >
    >      private static String hexString( byte[] bytes )
    >      {
    >          StringBuilder sb = new StringBuilder( bytes.length *2 );
    >          for( int i = 0; i < bytes.length; i++ ) {
    >              sb.append(  String.format( "%02X", bytes ));
    >          }
    >          return sb.toString();
    > //        return local.utils.ArrayUtils.toFormattedString( "%02X",
    > //bytes, null );
    >      }
    >
    > }


    This seems enough, with that I can:

    Key
    Plaintext
    A2B93E8F6F023A078E

    now how to decode the string "A2B93E8F6F023A078E" back to "Plaintext"?
    thanks
     
    Angelo Chen, Mar 24, 2009
    #14
  15. Mark Space Guest

    Angelo Chen wrote:

    > This seems enough, with that I can:
    >
    > Key
    > Plaintext
    > A2B93E8F6F023A078E
    >
    > now how to decode the string "A2B93E8F6F023A078E" back to "Plaintext"?



    That's not what I get. Check your tests with Wikipedia. The
    cipher-text for Key and Plaintext is "BBF316E8D940AF0AD3", which is what
    the program I posted prints.

    But for how to decrypt, RC4 is symmetric. That means you decrypt with
    the same key and algorithm you encrypt with.

    package local;

    public class Rc4
    {
    private byte[] state = new byte[256];
    int x, y;

    public Rc4( byte[] key )
    {
    // if( key.length<5||key.length>16 )
    // {
    // throw new IllegalArgumentException( "Key: "+key+
    // " must be between 40 and 128 bits. (key length is //"+
    // key.length+".)" );
    // }
    for( int i = 0; i < state.length; i++ ) {
    state = (byte) i;
    }
    for( int i = 0; i < state.length; i++ ) {
    x = (x + key[i % key.length] + state) & 0xFF;
    byte swap = state;
    state = state[x];
    state[x] = swap;
    }
    x = 0;
    }

    public byte[] crypt( byte[] input )
    {
    byte[] output = new byte[input.length];
    for( int i = 0; i < input.length; i++ ) {
    x = (x + 1) % 256;
    y = (state[x] + y) & 0xFF;
    byte swap = state[x];
    state[x] = state[y];
    state[y] = swap;
    byte r = state[(state[x] + state[y]) & 0xFF];
    output = (byte) (input ^ r);
    }
    return output;
    }

    public static void main( final String... args )
    {
    String[][] testVectors = {{"Key", "Plaintext"},
    {"Wiki", "pedia"}, {"Secret", "Attack at dawn"},
    };
    for( String[] s : testVectors ) {
    System.out.printf( "RC4( \"%s\", \"%s\" ) => ",
    s[0], s[1] );
    System.out.println( hexString( new Rc4( s[0].getBytes() )
    .crypt( s[1].getBytes() ) ) );
    }
    String [][] reverseVectors = {
    {"Key", "BBF316E8D940AF0AD3" },
    {"Wiki", "1021BF0420" },
    {"Secret", "45A01F645FC35B383552544B9BF5" }
    };
    for( String[] s : reverseVectors ) {
    System.out.printf( "RC4( \"%s\", \"%s\" ) => ",
    s[0], s[1] );
    byte[] bytes = new byte[s[1].length()/2];
    for( int i = 0; i < bytes.length; i++ ) {
    bytes = (byte)Integer.parseInt( s[1]
    .substring( i*2, i*2+2), 16 );
    }
    System.out.println( new String( new Rc4( s[0].getBytes() )
    .crypt( bytes ) ) );
    }
    }

    private static String hexString( byte[] bytes )
    {
    StringBuilder sb = new StringBuilder( bytes.length *2 );
    for( int i = 0; i < bytes.length; i++ ) {
    sb.append( String.format( "%02X", bytes ));
    }
    return sb.toString();
    }
    }
     
    Mark Space, Mar 24, 2009
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Srinivasa Reddy K Ganji

    database connection string encryption and decryption

    Srinivasa Reddy K Ganji, Jul 18, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    713
    Gary Varga
    Jul 18, 2003
  2. Replies:
    2
    Views:
    1,618
    Sushant Bhatia
    May 3, 2005
  3. Rogue Chameleon

    Encryption & Decryption

    Rogue Chameleon, Sep 23, 2004, in forum: Java
    Replies:
    6
    Views:
    585
  4. Bruce
    Replies:
    3
    Views:
    278
    Anthony Jones
    Dec 13, 2007
  5. stig

    simple encryption/decryption

    stig, Jan 18, 2005, in forum: Perl Misc
    Replies:
    3
    Views:
    251
Loading...

Share This Page