Better AES Encryption

Results 1 to 10 of 10
  1. #1
    Account Upgraded | Title Enabled! ExtremeDevilz is offline
    MemberRank
    Apr 2008 Join Date
    647Posts

    Better AES Encryption

    hello guys this following is a rewrite of odin aes encryption using bouncycastle and methods rename, so no need to download jce policy and copy it around just get the bouncycastle jar will do :) let me know if the following can be improved further more :) also this is based on v144

    thanks @Diamondo25 for the neat version in mapleshark

    Code:
    /*
        This file is part of the OdinMS Maple Story Server
        Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
                   Matthias Butz <matze@odinms.de>
                   Jan Christian Meyer <vimes@odinms.de>
    
    
        This program is free software: you can redistribute it and/or modify
        it under the terms of the GNU Affero General Public License as
        published by the Free Software Foundation version 3 as published by
        the Free Software Foundation. You may not use, modify or distribute
        this program under any other version of the GNU Affero General Public
        License.
    
    
        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU Affero General Public License for more details.
    
    
        You should have received a copy of the GNU Affero General Public License
        along with this program.  If not, see <http://www.gnu.org/licenses/>.
    */
    
    
    package tools;
    
    
    
    
    import java.security.InvalidKeyException;
    import java.security.Key;
    import java.security.NoSuchAlgorithmException;
    import java.security.NoSuchProviderException;
    import java.security.Security;
    
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.spec.SecretKeySpec;
    
    
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    
    
    import sun.security.provider.SecureRandom;
    
    
    /*
     *  @author Frz
     *  @author Multo
     * 
     */
    
    
    public class MapleAESOFB {
        private byte iv[];
        private Cipher cipher;
        private short mapleVersion;
    
    
        private static final byte[] secretKey = {
                   0x46, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 
                   0x3C, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)
                   0xA3, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)
                   0xB6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)
                   0x2F, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)
                   0xAE, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 
                   0x57, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)
                   0xB7, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
        
        private static final byte[] shuffleKey = { (byte) 0xEC, (byte) 0x3F, (byte) 0x77, (byte) 0xA4, (byte) 0x45, (byte) 0xD0, (byte) 0x71, (byte) 0xBF, (byte) 0xB7, (byte) 0x98, (byte) 0x20, (byte) 0xFC,
            (byte) 0x4B, (byte) 0xE9, (byte) 0xB3, (byte) 0xE1, (byte) 0x5C, (byte) 0x22, (byte) 0xF7, (byte) 0x0C, (byte) 0x44, (byte) 0x1B, (byte) 0x81, (byte) 0xBD, (byte) 0x63, (byte) 0x8D, (byte) 0xD4, (byte) 0xC3,
            (byte) 0xF2, (byte) 0x10, (byte) 0x19, (byte) 0xE0, (byte) 0xFB, (byte) 0xA1, (byte) 0x6E, (byte) 0x66, (byte) 0xEA, (byte) 0xAE, (byte) 0xD6, (byte) 0xCE, (byte) 0x06, (byte) 0x18, (byte) 0x4E, (byte) 0xEB,
            (byte) 0x78, (byte) 0x95, (byte) 0xDB, (byte) 0xBA, (byte) 0xB6, (byte) 0x42, (byte) 0x7A, (byte) 0x2A, (byte) 0x83, (byte) 0x0B, (byte) 0x54, (byte) 0x67, (byte) 0x6D, (byte) 0xE8, (byte) 0x65, (byte) 0xE7,
            (byte) 0x2F, (byte) 0x07, (byte) 0xF3, (byte) 0xAA, (byte) 0x27, (byte) 0x7B, (byte) 0x85, (byte) 0xB0, (byte) 0x26, (byte) 0xFD, (byte) 0x8B, (byte) 0xA9, (byte) 0xFA, (byte) 0xBE, (byte) 0xA8, (byte) 0xD7,
            (byte) 0xCB, (byte) 0xCC, (byte) 0x92, (byte) 0xDA, (byte) 0xF9, (byte) 0x93, (byte) 0x60, (byte) 0x2D, (byte) 0xDD, (byte) 0xD2, (byte) 0xA2, (byte) 0x9B, (byte) 0x39, (byte) 0x5F, (byte) 0x82, (byte) 0x21,
            (byte) 0x4C, (byte) 0x69, (byte) 0xF8, (byte) 0x31, (byte) 0x87, (byte) 0xEE, (byte) 0x8E, (byte) 0xAD, (byte) 0x8C, (byte) 0x6A, (byte) 0xBC, (byte) 0xB5, (byte) 0x6B, (byte) 0x59, (byte) 0x13, (byte) 0xF1,
            (byte) 0x04, (byte) 0x00, (byte) 0xF6, (byte) 0x5A, (byte) 0x35, (byte) 0x79, (byte) 0x48, (byte) 0x8F, (byte) 0x15, (byte) 0xCD, (byte) 0x97, (byte) 0x57, (byte) 0x12, (byte) 0x3E, (byte) 0x37, (byte) 0xFF,
            (byte) 0x9D, (byte) 0x4F, (byte) 0x51, (byte) 0xF5, (byte) 0xA3, (byte) 0x70, (byte) 0xBB, (byte) 0x14, (byte) 0x75, (byte) 0xC2, (byte) 0xB8, (byte) 0x72, (byte) 0xC0, (byte) 0xED, (byte) 0x7D, (byte) 0x68,
            (byte) 0xC9, (byte) 0x2E, (byte) 0x0D, (byte) 0x62, (byte) 0x46, (byte) 0x17, (byte) 0x11, (byte) 0x4D, (byte) 0x6C, (byte) 0xC4, (byte) 0x7E, (byte) 0x53, (byte) 0xC1, (byte) 0x25, (byte) 0xC7, (byte) 0x9A,
            (byte) 0x1C, (byte) 0x88, (byte) 0x58, (byte) 0x2C, (byte) 0x89, (byte) 0xDC, (byte) 0x02, (byte) 0x64, (byte) 0x40, (byte) 0x01, (byte) 0x5D, (byte) 0x38, (byte) 0xA5, (byte) 0xE2, (byte) 0xAF, (byte) 0x55,
            (byte) 0xD5, (byte) 0xEF, (byte) 0x1A, (byte) 0x7C, (byte) 0xA7, (byte) 0x5B, (byte) 0xA6, (byte) 0x6F, (byte) 0x86, (byte) 0x9F, (byte) 0x73, (byte) 0xE6, (byte) 0x0A, (byte) 0xDE, (byte) 0x2B, (byte) 0x99,
            (byte) 0x4A, (byte) 0x47, (byte) 0x9C, (byte) 0xDF, (byte) 0x09, (byte) 0x76, (byte) 0x9E, (byte) 0x30, (byte) 0x0E, (byte) 0xE4, (byte) 0xB2, (byte) 0x94, (byte) 0xA0, (byte) 0x3B, (byte) 0x34, (byte) 0x1D,
            (byte) 0x28, (byte) 0x0F, (byte) 0x36, (byte) 0xE3, (byte) 0x23, (byte) 0xB4, (byte) 0x03, (byte) 0xD8, (byte) 0x90, (byte) 0xC8, (byte) 0x3C, (byte) 0xFE, (byte) 0x5E, (byte) 0x32, (byte) 0x24, (byte) 0x50,
            (byte) 0x1F, (byte) 0x3A, (byte) 0x43, (byte) 0x8A, (byte) 0x96, (byte) 0x41, (byte) 0x74, (byte) 0xAC, (byte) 0x52, (byte) 0x33, (byte) 0xF0, (byte) 0xD9, (byte) 0x29, (byte) 0x80, (byte) 0xB1, (byte) 0x16,
            (byte) 0xD3, (byte) 0xAB, (byte) 0x91, (byte) 0xB9, (byte) 0x84, (byte) 0x7F, (byte) 0x61, (byte) 0x1E, (byte) 0xCF, (byte) 0xC5, (byte) 0xD1, (byte) 0x56, (byte) 0x3D, (byte) 0xCA, (byte) 0xF4, (byte) 0x05,
            (byte) 0xC6, (byte) 0xE5, (byte) 0x08, (byte) 0x49};
    
    
        public MapleAESOFB(byte iv[], short mapleVersion) {
                Key pKey = new SecretKeySpec(secretKey, "AES");
                SecureRandom pRandom = new SecureRandom();
                pRandom.engineNextBytes(iv);
                Security.addProvider(new BouncyCastleProvider());
                try {
                    cipher = Cipher.getInstance("AES/OFB/NoPadding", "BC");
                    cipher.init(Cipher.ENCRYPT_MODE, pKey);
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (NoSuchProviderException e) {
                    e.printStackTrace();
                } catch (NoSuchPaddingException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                }
                this.setIv(iv);
                this.mapleVersion = (short) (((mapleVersion >> 8) & 0xFF) | ((mapleVersion << 8) & 0xFF00));
        }
    
    
        private void setIv(byte[] iv) {
            this.iv = iv;
        }
    
    
        private static byte[] multiplyBytes(byte[] in, int count, int mul) {
            byte[] ret = new byte[count * mul];
            for (int x = 0; x < count * mul; x++) {
                ret[x] = in[x % count];
            }
            return ret;
        }
    
    
        public byte[] crypt(byte[] data) {
            int remaining = data.length;
            int llength = 0x5B0;
            int start = 0;
            while (remaining > 0) {
                byte[] myIv = multiplyBytes(this.iv, 4, 4);
                if (remaining < llength) {
                    llength = remaining;
                }
                for (int x = start; x < (start + llength); x++) {
                    if ((x - start) % myIv.length == 0) {
                        try {
                            byte[] newIv = cipher.doFinal(myIv);
                            for (int j = 0; j < myIv.length; j++) {
                                myIv[j] = newIv[j];
                            }
                        } catch (IllegalBlockSizeException e) {
                        } catch (BadPaddingException e) {
                        }
                    }
                    data[x] ^= myIv[(x - start) % myIv.length];
                }
                start += llength;
                remaining -= llength;
                llength = 0x5B4;
            }
            updateIv();
            return data;
        }
    
    
        private void updateIv() {
            this.iv = getNewIv(this.iv);
        }
    
    
        public byte[] getPacketHeader(int length) {
            int iiv = (iv[3]) & 0xFF;
            iiv |= (iv[2] << 8) & 0xFF00;
            iiv ^= mapleVersion;
            int mlength = ((length << 8) & 0xFF00) | (length >>> 8);
            int xoredIv = iiv ^ mlength;
            byte[] ret = new byte[4];
            ret[0] = (byte) ((iiv >>> 8) & 0xFF);
            ret[1] = (byte) (iiv & 0xFF);
            ret[2] = (byte) ((xoredIv >>> 8) & 0xFF);
            ret[3] = (byte) (xoredIv & 0xFF);
            return ret;
        }
    
    
        public static int getPacketLength(int packetHeader) {
            int packetLength = ((packetHeader >>> 16) ^ (packetHeader & 0xFFFF));
            packetLength = ((packetLength << 8) & 0xFF00) | ((packetLength >>> 8) & 0xFF);
            return packetLength;
        }
    
    
        public boolean checkPacket(byte[] packet) {
            return ((((packet[0] ^ iv[2]) & 0xFF) == ((mapleVersion >> 8) & 0xFF)) && (((packet[1] ^ iv[3]) & 0xFF) == (mapleVersion & 0xFF)));
        }
    
    
        public boolean checkPacket(int packetHeader) {
            byte packetHeaderBuf[] = new byte[2];
            packetHeaderBuf[0] = (byte) ((packetHeader >> 24) & 0xFF);
            packetHeaderBuf[1] = (byte) ((packetHeader >> 16) & 0xFF);
            return checkPacket(packetHeaderBuf);
        }
    
    
        public static byte[] getNewIv(byte oldIv[]) {
            byte[] newIv = {(byte) 0xf2, 0x53, (byte) 0x50, (byte) 0xc6};
            for (int x = 0; x < 4; x++) {
                Shuffle(oldIv[x], newIv);
            }
            return newIv;
        }
            
       private static byte[] Shuffle(byte inputValue, byte[] pIv) {
             byte input = inputValue;
             byte tableInput = shuffleKey[input];
             pIv[0] += (byte)(shuffleKey[pIv[1]] - input);
             pIv[1] -= (byte)(pIv[2] ^ tableInput);
             pIv[2] ^= (byte)(shuffleKey[pIv[3]] + input);
             pIv[3] -= (byte)(pIv[0] - tableInput);
             
             int Value = (int) (pIv[0]) & 0xFF | (pIv[1] << 8) & 0xFF00 | (pIv[2] << 16) & 0xFF0000 | (pIv[3] << 24) & 0xFF000000;
             Value = (Value >> 0x1D | Value << 0x03);
             
             pIv[0] = (byte)(Value & 0xFF);
             pIv[1] = (byte)((Value >> 8) & 0xFF);
             pIv[2] = (byte)((Value >> 16) & 0xFF);
             pIv[3] = (byte)((Value >> 24) & 0xFF);
            
             return pIv;
             
        }
    }


  2. #2
    BloopBloop Hilia is offline
    MemberRank
    Aug 2012 Join Date
    905Posts

    Re: Better AES Encryption

    Might as well add the flags used to set different algorithm's. Also i am pretty sure the jit will optimize this to the same assembly as with the previous code.

  3. #3
    I'm overrated. Fraysa is offline
    MemberRank
    Apr 2008 Join Date
    4,891Posts

    Re: Better AES Encryption

    How is this better? Care to explain?

    Also.. WTF?

    Quote Originally Posted by Multo View Post
    Code:
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (NoSuchProviderException e) {
                    e.printStackTrace();
                } catch (NoSuchPaddingException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                }
    }

  4. #4
    BloopBloop Hilia is offline
    MemberRank
    Aug 2012 Join Date
    905Posts

    Re: Better AES Encryption

    Quote Originally Posted by Fraysa View Post
    How is this better? Care to explain?

    Also.. WTF?
    I didn't even saw that one. And yes unless you (multo/extremedevil etc...) mind implementing some kind of different handling for all those different exceptions,better use one try catch

    About what he changed:
    Code:
     private static byte[] funnyShit(byte inputByte, byte[] in) {
            byte elina = in[1];
            byte anna = inputByte;
            byte moritz = funnyBytes[(int) elina & 0xFF];
            moritz -= inputByte;
            in[0] += moritz;
            moritz = in[2];
            moritz ^= funnyBytes[(int) anna & 0xFF];
            elina -= (int) moritz & 0xFF;
            in[1] = elina;
            elina = in[3];
            moritz = elina;
            elina -= (int) in[0] & 0xFF;
            moritz = funnyBytes[(int) moritz & 0xFF];
            moritz += inputByte;
            moritz ^= in[2];
            in[2] = moritz;
            elina += (int) funnyBytes[(int) anna & 0xFF] & 0xFF;
            in[3] = elina;
            int merry = ((int) in[0]) & 0xFF;
            merry |= (in[1] << 8) & 0xFF00;
            merry |= (in[2] << 16) & 0xFF0000;
            merry |= (in[3] << 24) & 0xFF000000;
            int ret_value = merry;
            ret_value = ret_value >>> 0x1d;
            merry = merry << 3;
            ret_value = ret_value | merry;
            in[0] = (byte) (ret_value & 0xFF);
            in[1] = (byte) ((ret_value >> 8) & 0xFF);
            in[2] = (byte) ((ret_value >> 16) & 0xFF);
            in[3] = (byte) ((ret_value >> 24) & 0xFF);
            return in;
        }
    TO

    Nexon names it "MorphKey",if someone cares
    Code:
      private static byte[] Shuffle(byte inputValue, byte[] pIv) {
             byte input = inputValue;
             byte tableInput = shuffleKey[input];
             pIv[0] += (byte)(shuffleKey[pIv[1]] - input);
             pIv[1] -= (byte)(pIv[2] ^ tableInput);
             pIv[2] ^= (byte)(shuffleKey[pIv[3]] + input);
             pIv[3] -= (byte)(pIv[0] - tableInput);
             
             int Value = (int) (pIv[0]) & 0xFF | (pIv[1] << 8) & 0xFF00 | (pIv[2] << 16) & 0xFF0000 | (pIv[3] << 24) & 0xFF000000;
             Value = (Value >> 0x1D | Value << 0x03);
             
             pIv[0] = (byte)(Value & 0xFF);
             pIv[1] = (byte)((Value >> 8) & 0xFF);
             pIv[2] = (byte)((Value >> 16) & 0xFF);
             pIv[3] = (byte)((Value >> 24) & 0xFF);
            
             return pIv;
             
        }

  5. #5
    I'm overrated. Fraysa is offline
    MemberRank
    Apr 2008 Join Date
    4,891Posts

    Re: Better AES Encryption

    If that's what he changed then this is not an improvement at all, it's a mere code rewrite for one method.

  6. #6
    Valued Member Minike is offline
    MemberRank
    Apr 2013 Join Date
    115Posts

    Re: Better AES Encryption

    You did not contribute the slightest bit in this code, yet you have guts of naming yourself the author of this.
    Personally I think the version Diamondo made is quite the mess and I doubt if it's any better than the old odin code.
    But as you copied it, I doubt mentioning the flaws to you wont help much.

    Oww, and did you even test this? (I was actually going to ask if you benchmarked this, but never mind)
    Code:
    Value = (Value >> 0x1D | Value << 0x03);         
             pIv[0] = (byte)(Value & 0xFF);
             pIv[1] = (byte)((Value >> 8) & 0xFF);
             pIv[2] = (byte)((Value >> 16) & 0xFF);
             pIv[3] = (byte)((Value >> 24) & 0xFF);
    I aint no Java pro, but I do not think this is how shuffling works in Java

  7. #7
    Novice FFSMan is offline
    MemberRank
    Apr 2015 Join Date
    4Posts

    Re: Better AES Encryption

    If this was just because of the nuisance of having to copy those files everywhere, here is an alternative solution. (Requires Java 7+)

    Add the following methods under the main method of server.Start

    PHP Code:
        /**
         * Credits: ntoskrnl of StackOverflow
         * http://stackoverflow.com/questions/1179672/
         * 
         */
        private static void removeCryptographyRestrictions() {
            if (!isRestrictedCryptography()) {
                System.out.println("Cryptography restrictions removal not needed");
                return;
            }
            try {
                /*
                 * Do the following, but with reflection to bypass access checks:
                 *
                 * JceSecurity.isRestricted = false;
                 * JceSecurity.defaultPolicy.perms.clear();
                 * JceSecurity.defaultPolicy.add(CryptoAllPermission.INSTANCE);
                 */
                final Class<?jceSecurity = Class.forName("javax.crypto.JceSecurity");
                final Class<
    ?> cryptoPermissions = Class.forName("javax.crypto.CryptoPermissions");
                final Class<?cryptoAllPermission = Class.forName("javax.crypto.CryptoAllPermission");


                final 
    Field isRestrictedField jceSecurity.getDeclaredField("isRestricted");
                
    isRestrictedField.setAccessible(true);
                
    isRestrictedField.set(nullfalse);


                final 
    Field defaultPolicyField jceSecurity.getDeclaredField("defaultPolicy");
                
    defaultPolicyField.setAccessible(true);
                final 
    PermissionCollection defaultPolicy = (PermissionCollectiondefaultPolicyField.get(null);


                final 
    Field perms cryptoPermissions.getDeclaredField("perms");
                
    perms.setAccessible(true);
                ((
    Map<?, ?>) perms.get(defaultPolicy)).clear();


                final Field instance = cryptoAllPermission.getDeclaredField("INSTANCE");
                instance.setAccessible(true);
                defaultPolicy.add((Permission) instance.get(null));


                System.out.println("\t\tSuccessfully removed cryptography restrictions");
            } catch (final Exception e) {
                System.err.println("\t\tFailed to remove cryptography restrictions");
                e.printStackTrace();
            }
        }


        private static boolean isRestrictedCryptography() {
            // This simply matches the Oracle JRE, but not OpenJDK.
            return "Java(TM) SE Runtime Environment".equals(System.getProperty("java.runtime.name"));
        }
    Then add this line as the first line under the main method
    PHP Code:
    Start.removeCryptographyRestrictions(); 
    Last edited by FFSMan; 23-07-15 at 11:07 PM.

  8. #8
    Account Upgraded | Title Enabled! ExtremeDevilz is offline
    MemberRank
    Apr 2008 Join Date
    647Posts

    Re: Better AES Encryption

    The code was a rewrite to use bouncy castle etc, I'm still working on a better improvement and will update the thread once I find it better

  9. #9
    I'm overrated. Fraysa is offline
    MemberRank
    Apr 2008 Join Date
    4,891Posts

    Re: Better AES Encryption

    Quote Originally Posted by Multo View Post
    The code was a rewrite to use bouncy castle etc, I'm still working on a better improvement and will update the thread once I find it better
    I think you're looking at the wrong place. I doubt you even know what bouncy castle is, considering the fact you can't explain how this is this better than JCE. Let me tell you do this - performance wise it is the same. There's no real reason to use BC unless you really need it.. but you don't. You didn't even refactor the code, so there isn't a slight improvement here.

    Like I said it before, Multo, instead of wasting your time googling you better waste it on studying new things and actually release something useful.

    EDIT: Go ahead, dislike my post. This just proves you're here to release crap to gain e-fame and not learn or contribute anything. People like you are the reason this section lost its' good men.
    Last edited by Fraysa; 24-07-15 at 07:20 AM.

  10. #10
    Everything is possible~ Diamondo25 is offline
    MemberRank
    Jan 2008 Join Date
    The NetherlandsLocation
    1,116Posts

    Re: Better AES Encryption

    > sees mention about neat mapleshark code
    > sees that AES transform is still the same

    I suggest you also copy that code over, because the original mapleshark aes transform code was weird.
    https://github.com/diamondo25/MapleS...pleAES.cs#L108



Advertisement