⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iso9797alg3mac.java

📁 kmlnjlkj nlkjlkjkljl okopokipoipo oipipipo i
💻 JAVA
字号:
package org.bouncycastle.crypto.macs;import org.bouncycastle.crypto.BlockCipher;import org.bouncycastle.crypto.CipherParameters;import org.bouncycastle.crypto.Mac;import org.bouncycastle.crypto.engines.DESEngine;import org.bouncycastle.crypto.modes.CBCBlockCipher;import org.bouncycastle.crypto.paddings.BlockCipherPadding;import org.bouncycastle.crypto.params.KeyParameter;/** * DES based CBC Block Cipher MAC according to ISO9797, algorithm 3 (ANSI X9.19 Retail MAC) * * This could as well be derived from CBCBlockCipherMac, but then the property mac in the base * class must be changed to protected   */public class ISO9797Alg3Mac     implements Mac {    private byte[]              mac;        private byte[]              buf;    private int                 bufOff;    private BlockCipher         cipher;    private BlockCipherPadding  padding;        private int                 macSize;    private KeyParameter        lastKey2;    private KeyParameter        lastKey3;        /**     * create a Retail-MAC based on a CBC block cipher. This will produce an     * authentication code of the length of the block size of the cipher.     *     * @param cipher the cipher to be used as the basis of the MAC generation. This must     * be DESEngine.     */    public ISO9797Alg3Mac(            BlockCipher     cipher)    {        this(cipher, cipher.getBlockSize() * 8, null);    }        /**     * create a Retail-MAC based on a CBC block cipher. This will produce an     * authentication code of the length of the block size of the cipher.     *     * @param cipher the cipher to be used as the basis of the MAC generation.     * @param padding the padding to be used to complete the last block.     */    public ISO9797Alg3Mac(        BlockCipher         cipher,        BlockCipherPadding  padding)    {        this(cipher, cipher.getBlockSize() * 8, padding);    }    /**     * create a Retail-MAC based on a block cipher with the size of the     * MAC been given in bits. This class uses single DES CBC mode as the basis for the     * MAC generation.     * <p>     * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81),     * or 16 bits if being used as a data authenticator (FIPS Publication 113),     * and in general should be less than the size of the block cipher as it reduces     * the chance of an exhaustive attack (see Handbook of Applied Cryptography).     *     * @param cipher the cipher to be used as the basis of the MAC generation.     * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8.     */    public ISO9797Alg3Mac(        BlockCipher     cipher,        int             macSizeInBits)    {        this(cipher, macSizeInBits, null);    }    /**     * create a standard MAC based on a block cipher with the size of the     * MAC been given in bits. This class uses single DES CBC mode as the basis for the     * MAC generation. The final block is decrypted and then encrypted using the     * middle and right part of the key.     * <p>     * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81),     * or 16 bits if being used as a data authenticator (FIPS Publication 113),     * and in general should be less than the size of the block cipher as it reduces     * the chance of an exhaustive attack (see Handbook of Applied Cryptography).     *     * @param cipher the cipher to be used as the basis of the MAC generation.     * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8.     * @param padding the padding to be used to complete the last block.     */    public ISO9797Alg3Mac(        BlockCipher         cipher,        int                 macSizeInBits,        BlockCipherPadding  padding)    {        if ((macSizeInBits % 8) != 0)        {            throw new IllegalArgumentException("MAC size must be multiple of 8");        }        if (!(cipher instanceof DESEngine))        {            throw new IllegalArgumentException("cipher must be instance of DESEngine");        }        this.cipher = new CBCBlockCipher(cipher);        this.padding = padding;        this.macSize = macSizeInBits / 8;        mac = new byte[cipher.getBlockSize()];        buf = new byte[cipher.getBlockSize()];        bufOff = 0;    }        public String getAlgorithmName()    {        return "ISO9797Alg3";    }    public void init(CipherParameters params)    {        reset();        if (!(params instanceof KeyParameter))        {            throw new IllegalArgumentException(                    "params must be an instance of KeyParameter");        }        // KeyParameter must contain a double or triple length DES key,        // however the underlying cipher is a single DES. The middle and        // right key are used only in the final step.        KeyParameter kp = (KeyParameter)params;        KeyParameter key1;        byte[] keyvalue = kp.getKey();        if (keyvalue.length == 16)        { // Double length DES key            key1 = new KeyParameter(keyvalue, 0, 8);            this.lastKey2 = new KeyParameter(keyvalue, 8, 8);            this.lastKey3 = key1;        }        else if (keyvalue.length == 24)        { // Triple length DES key            key1 = new KeyParameter(keyvalue, 0, 8);            this.lastKey2 = new KeyParameter(keyvalue, 8, 8);            this.lastKey3 = new KeyParameter(keyvalue, 16, 8);        }        else        {            throw new IllegalArgumentException(                    "Key must be either 112 or 168 bit long");        }        cipher.init(true, key1);    }        public int getMacSize()    {        return macSize;    }        public void update(            byte        in)    {        if (bufOff == buf.length)        {            cipher.processBlock(buf, 0, mac, 0);            bufOff = 0;        }                buf[bufOff++] = in;    }            public void update(            byte[]      in,            int         inOff,            int         len)    {        if (len < 0)        {            throw new IllegalArgumentException("Can't have a negative input length!");        }                int blockSize = cipher.getBlockSize();        int resultLen = 0;        int gapLen = blockSize - bufOff;                if (len > gapLen)        {            System.arraycopy(in, inOff, buf, bufOff, gapLen);                        resultLen += cipher.processBlock(buf, 0, mac, 0);                        bufOff = 0;            len -= gapLen;            inOff += gapLen;                        while (len > blockSize)            {                resultLen += cipher.processBlock(in, inOff, mac, 0);                                len -= blockSize;                inOff += blockSize;            }        }                System.arraycopy(in, inOff, buf, bufOff, len);                bufOff += len;    }        public int doFinal(            byte[]  out,            int     outOff)    {        int blockSize = cipher.getBlockSize();                if (padding == null)        {            //            // pad with zeroes            //            while (bufOff < blockSize)            {                buf[bufOff] = 0;                bufOff++;            }        }        else        {            if (bufOff == blockSize)            {                cipher.processBlock(buf, 0, mac, 0);                bufOff = 0;            }                        padding.addPadding(buf, bufOff);        }                cipher.processBlock(buf, 0, mac, 0);        // Added to code from base class        DESEngine deseng = new DESEngine();                deseng.init(false, this.lastKey2);        deseng.processBlock(mac, 0, mac, 0);                deseng.init(true, this.lastKey3);        deseng.processBlock(mac, 0, mac, 0);        // ****                System.arraycopy(mac, 0, out, outOff, macSize);                reset();                return macSize;    }        /**     * Reset the mac generator.     */    public void reset()    {        /*         * clean the buffer.         */        for (int i = 0; i < buf.length; i++)        {            buf[i] = 0;        }                bufOff = 0;                /*         * reset the underlying cipher.         */        cipher.reset();    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -