RSA/ECB/OAEPWithSHA-1AndMGF1Padding 类似工具类 代码

源码

MGF1

import java.security.MessageDigest;

/**
 * 掩模生成函数
 * mask generator function, as described in PKCS1v2.
 */
public class MGF1
{
    private MessageDigest digest;

    /**
     * Create a version of MGF1 for the given digest.
     *
     * @param digest
     *            digest to use as the basis of the function.
     */
    public MGF1(MessageDigest digest)
    {
        this.digest = digest;
    }

    /**
     * int to octet string.
     */
    private void I2OSP(int i, byte[] sp)
    {
        sp[0] = (byte) (i >>> 24);
        sp[1] = (byte) (i >>> 16);
        sp[2] = (byte) (i >>> 8);
        sp[3] = (byte) (i >>> 0);
    }

    /**
     * Generate the mask.
     *
     * @param seed
     *            source of input bytes for initial digest state
     * @param length
     *            length of mask to generate
     *
     * @return a byte array containing a MGF1 generated mask
     */
    public byte[]
    generateMask(byte[] seed, int length)
    {
        byte[] mask = new byte[length];
        byte[] C = new byte[4];
        int counter = 0;
        int hLen = digest.getDigestLength();
        digest.reset();
        while (counter < (length / hLen))
        {
            I2OSP(counter, C);
            digest.update(seed);
            digest.update(C);//update 就是把之前的跟现在的连接在一起
            System.arraycopy(digest.digest(), 0, mask, counter * hLen, hLen);

            counter++;
        }
        if ((counter * hLen) < length)
        {
            I2OSP(counter, C);
            digest.update(seed);
            digest.update(C);
            System.arraycopy(digest.digest(), 0, mask, counter * hLen,
                    mask.length - (counter * hLen));
        }
        return mask;
    }
}

SHA


import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHAUtils {
    /**
     * @param strSrc
     * @param encName :SHA-1;SHA-224;SHA-256;SHA-386;SHA-512;
     * @return
     */
    public static byte[] encrypt(String strSrc, String encName) {
        MessageDigest md = null;
        byte[] encode = null;

        try {
            byte[] bt = strSrc.getBytes("UTF-8");
            md = MessageDigest.getInstance(encName);
            md.update(bt);
            encode = md.digest();
        } catch (NoSuchAlgorithmException e) {
            return null;
        } catch (UnsupportedEncodingException e) {
            return null;
        }
        return encode;
    }

    public static byte[] encryptSHA1(String strSrc) {
        return encrypt(strSrc, "SHA-1");
    }

    public static byte[] encryptSHA224(String strSrc) {
        return encrypt(strSrc, "SHA-224");
    }

    public static byte[] encryptSHA256(String strSrc) {
        return encrypt(strSrc, "SHA-256");
    }

    public static byte[] encryptSHA384(String strSrc) {
        return encrypt(strSrc, "SHA-384");
    }

    public static byte[] encryptSHA512(String strSrc) {
        return encrypt(strSrc, "SHA-512");
    }

}

oeap 编解码


import android.support.annotation.IntDef;
import android.support.annotation.StringDef;
import android.text.TextUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Arrays;

/**
 * @author ricardo
 * @date 2020/10/28.
 * description:
 */
public class OAEPUtils {

    /**
     * @hide
     */
    @IntDef(flag = true, value = {
            BLOCK_SIZE_2048,
            BLOCK_SIZE_4096
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface BlockSize {
    }

    public static final int BLOCK_SIZE_2048 = 2048 / 8;
    public static final int BLOCK_SIZE_4096 = 4096 / 8;

    /**
     * @hide
     */
    @StringDef(value = {
            SHA_1,
            SHA_224,
            SHA_256,
            SHA_384,
            SHA_512
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface HashName {
    }

    public static final String SHA_1 = "SHA-1";
    public static final String SHA_224 = "SHA-224";
    public static final String SHA_256 = "SHA-256";
    public static final String SHA_384 = "SHA-384";
    public static final String SHA_512 = "SHA-512";
  public static byte[] rsaOAEPMGF1SHA1PaddingEMEncode(byte[] sourceData, @HashName String hashName, String label, @BlockSize int blockSize) throws Exception {
        byte[] EM = null;
        if (sourceData == null || sourceData.length == 0) {
            return sourceData;
        }
        if (blockSize != BLOCK_SIZE_2048 || blockSize != BLOCK_SIZE_4096) {
            throw new Exception("block size error");
        }
        byte[] lHash = SHAUtils.encrypt(TextUtils.isEmpty(label) ? "" : label, hashName);
        if (lHash == null) {
            throw new Exception("hash error");
        }

        if (blockSize - 2 * lHash.length - 2 < sourceData.length) {
            throw new Exception(" data block size error");
        }

        byte[] ps = new byte[blockSize
                - sourceData.length - 2 * lHash.length - 2];
        for (int i = 0; i < ps.length; i++) {
            ps[i] = 0;
        }

        byte[] DB = new byte[blockSize
                - lHash.length - 1];
        System.arraycopy(lHash, 0, DB, 0, lHash.length);
        System.arraycopy(ps, 0, DB, lHash.length, ps.length);
        DB[lHash.length + ps.length] = 1;
        System.arraycopy(sourceData, 0, DB, lHash.length + ps.length + 1, sourceData.length);
        byte[] seed = SecureRandom.getSeed(lHash.length);

        MGF1 mgf1 = new MGF1(MessageDigest.getInstance(SHA_1));
        byte[] dbMask = mgf1.generateMask(seed, blockSize - lHash.length - 1);

        // DB和dbMask做异或运算生成maskedDB
        byte[] maskedDB = new BigInteger(DB).xor(new BigInteger(dbMask))
                .toByteArray();

        byte[] seedMask = mgf1.generateMask(maskedDB, lHash.length);

        // seed和seedMask做异或运算生成maskedSeed
        byte[] maskedSeed = new BigInteger(seed).xor(new BigInteger(seedMask))
                .toByteArray();

        EM = new byte[blockSize];
        EM[0] = 0;
        System.arraycopy(maskedSeed, 0, EM, 1, maskedSeed.length);
        System.arraycopy(maskedDB, 0, EM, maskedSeed.length + 1,
                maskedDB.length);
        return EM;
    }

    public static byte[] rsaOAEPMGF1SHA1PaddingEMDecode(byte[] EM, @HashName String hashName, String label, @BlockSize int blockSize) throws Exception {
        byte[] sourceData = null;
        if (EM == null || EM.length == 0 || EM.length != blockSize) {
            return sourceData;
        }
        if (blockSize != BLOCK_SIZE_2048 || blockSize != BLOCK_SIZE_4096) {
            throw new Exception("block size error");
        }
        byte[] lHash = SHAUtils.encrypt(TextUtils.isEmpty(label) ? "" : label, hashName);
        if (lHash == null) {
            throw new Exception("hash error");
        }
        byte[] maskSeed = Arrays.copyOfRange(EM, 1, lHash.length + 1);
        byte[] maskDB = Arrays.copyOfRange(EM, lHash.length + 1, EM.length);
        MGF1 mgf1 = new MGF1(MessageDigest.getInstance(SHA_1));
        byte[] seedMask = mgf1.generateMask(maskDB, lHash.length);
        byte[] seed = new BigInteger(maskSeed).xor(new BigInteger(seedMask)).toByteArray();
        byte[] dbMask = mgf1.generateMask(seed, blockSize - lHash.length - 1);
        byte[] DB = new BigInteger(maskDB).xor(new BigInteger(dbMask)).toByteArray();

        int index = -1;
        for (int k = 0; k < lHash.length; k++) {
            if (lHash[k] != DB[k]) {
                throw new Exception("hash error");
            }
        }
        for (int j = lHash.length; j < DB.length; j++) {
            if (DB[j] == 1) {
                index = j + 1;
                break;
            }
        }
        sourceData = Arrays.copyOfRange(DB, index, DB.length);
        return sourceData;
    }

}

以上供大家参考。其中MGF1-使用SHA1。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值