OAEPWithSHA-512AndMGF1Padding

来源:互联网 发布:unity3d 灯光开关 编辑:程序博客网 时间:2024/06/05 10:38

基于PKCS#1 V2.1规范的OAEPWithSHA-512AndMGF1Padding算法实现

java中可以直接使用RSA/ECB/OAEPWithSHA-512AndMGF1Padding来完成公钥加密数据。

例如:

public static byte[] encode(byte[] data) throws Exception{byte[] keyBytes = Base64Utils.getFromBASE64(key);X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);Key publicKey = keyFactory.generatePublic(x509KeySpec);Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-512AndMGF1Padding");cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data);}


其他语言与java语言对接时,可以参考如下填充算法实现过程:

package com.matrix.cipher;public abstract class Base64Utils{public static String encode(byte[] btData){int iLen = 0;boolean l_bFlag;int l_iGroup;char[] l_szData;byte[] l_btTmp;int ii;int jj;int kk;String l_stEncoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";if (btData == null){return null;}if ((iLen <= 0) || (iLen > btData.length)){iLen = btData.length;}l_bFlag = ((iLen % 3) == 0);l_iGroup = iLen / 3;ii = l_iGroup;if (!l_bFlag){ii++;}l_szData = new char[4 * ii];l_btTmp = new byte[3];for (ii = 0, jj = 0, kk = 0; ii < l_iGroup; ii++){l_btTmp[0] = btData[kk++];l_btTmp[1] = btData[kk++];l_btTmp[2] = btData[kk++];l_szData[jj++] = l_stEncoding.charAt((l_btTmp[0] >> 2) & 0x3F);l_szData[jj++] = l_stEncoding.charAt(((l_btTmp[0] & 0x03) << 4)| ((l_btTmp[1] >> 4) & 0x0F));l_szData[jj++] = l_stEncoding.charAt(((l_btTmp[1] & 0x0F) << 2)| ((l_btTmp[2] >> 6) & 0x03));l_szData[jj++] = l_stEncoding.charAt(l_btTmp[2] & 0x3F);}if (!l_bFlag){l_btTmp[0] = btData[kk++];l_szData[jj++] = l_stEncoding.charAt((l_btTmp[0] >> 2) & 0x3F);l_szData[jj + 1] = '=';l_szData[jj + 2] = '=';if ((iLen % 3) == 1){l_szData[jj] = l_stEncoding.charAt((l_btTmp[0] & 0x03) << 4);}else// if ((iLen % 3) == 2){l_btTmp[1] = btData[kk];l_szData[jj++] = l_stEncoding.charAt(((l_btTmp[0] & 0x03) << 4)| ((l_btTmp[1] >> 4) & 0x0F));l_szData[jj] = l_stEncoding.charAt((l_btTmp[1] & 0x0F) << 2);}}return new String(l_szData);}public static byte[] getFromBASE64(String stData){if (null == stData || stData.trim().isEmpty()){return null;}int l_iLen;int l_iGroup;int ii;int jj;int kk;boolean l_bFlag;char[] l_szTmp;byte[] l_btData = new byte[0];l_iLen = stData.length();if ((l_iLen % 4) != 0){return l_btData;}l_iGroup = l_iLen / 4;ii = l_iGroup * 3;l_bFlag = true;l_szTmp = new char[4];if (stData.charAt(l_iLen - 1) == '='){l_iLen--;ii--;l_iGroup--;l_bFlag = false;if (stData.charAt(l_iLen - 1) == '='){l_iLen--;ii--;}}for (jj = 0; jj < l_iLen; jj++){l_szTmp[0] = stData.charAt(jj);if (!((l_szTmp[0] == '+')|| (('/' <= l_szTmp[0]) && (l_szTmp[0] <= '9'))|| (('A' <= l_szTmp[0]) && (l_szTmp[0] <= 'Z')) || (('a' <= l_szTmp[0]) && (l_szTmp[0] <= 'z')))){return l_btData;}}l_btData = new byte[ii];for (ii = 0, jj = 0, kk = 0; ii < l_iGroup; ii++){l_szTmp[0] = returnToData(stData.charAt(kk++));l_szTmp[1] = returnToData(stData.charAt(kk++));l_szTmp[2] = returnToData(stData.charAt(kk++));l_szTmp[3] = returnToData(stData.charAt(kk++));l_btData[jj++] = (byte) ((l_szTmp[0] << 2) | ((l_szTmp[1] >> 4) & 0x03));l_btData[jj++] = (byte) ((l_szTmp[1] << 4) | ((l_szTmp[2] >> 2) & 0x0F));l_btData[jj++] = (byte) ((l_szTmp[2] << 6) | (l_szTmp[3] & 0x3F));}if (!l_bFlag){l_szTmp[0] = returnToData(stData.charAt(kk++));l_szTmp[1] = returnToData(stData.charAt(kk++));l_btData[jj++] = (byte) ((l_szTmp[0] << 2) | ((l_szTmp[1] >> 4) & 0x03));if ((l_iLen % 4) == 3){l_szTmp[2] = returnToData(stData.charAt(kk));l_btData[jj] = (byte) ((l_szTmp[1] << 4) | ((l_szTmp[2] >> 2) & 0x0F));}}return l_btData;}private static char returnToData(char cChar){if (('A' <= cChar) && (cChar <= 'Z')){cChar -= 'A';}else if (('a' <= cChar) && (cChar <= 'z')){cChar -= 'a';cChar += 26;}else if (('0' <= cChar) && (cChar <= '9')){cChar -= '0';cChar += 52;}else if (cChar == '+'){cChar = 62;}else// if (cChar == '/'){cChar = 63;}return cChar;}}



package com.matrix.cipher;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class SHAUtils{/** * @param strSrc * @param encName *            :SHA-1;SHA-256;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[] encryptSHA256(String strSrc){return encrypt(strSrc, "SHA-256");}public static byte[] encryptSHA512(String strSrc){return encrypt(strSrc, "SHA-512");}}



package com.matrix.cipher;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);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;}}



package com.matrix.cipher;import java.math.BigInteger;import java.security.KeyFactory;import java.security.MessageDigest;import java.security.SecureRandom;import java.security.interfaces.RSAPublicKey;import java.security.spec.X509EncodedKeySpec;import javax.crypto.Cipher;/** * @author Matrix * */public class RSA2048Utils{public static final String ALGORITHM = "RSA";private static String RSA_TRANSFORMATION = "RSA/ECB/NoPadding";/** * 首先要取得公钥,并使用setPublicKey方法来初始化变量key */public static String key;public static byte[] encode(byte[] data) throws Exception{byte[] keyBytes = Base64Utils.getFromBASE64(key);X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);Cipher cipher = Cipher.getInstance(RSA_TRANSFORMATION);cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] EM = OAEPWithSHA512AndMGF1Padding(data, publicKey);return cipher.doFinal(EM);}private static byte[] OAEPWithSHA512AndMGF1Padding(byte[] data,RSAPublicKey publicKey) throws Exception{byte[] lHash = SHAUtils.encrypt("", "SHA-512");byte[] ps = new byte[publicKey.getModulus().bitLength() / 8- data.length - 2 * lHash.length - 2];for (int i = 0; i < ps.length; i++){ps[i] = 0;}byte[] DB = new byte[publicKey.getModulus().bitLength() / 8- 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(data, 0, DB, lHash.length + ps.length + 1, data.length);byte[] seed = SecureRandom.getSeed(lHash.length);MGF1 mgf1 = new MGF1(MessageDigest.getInstance("SHA-1"));byte[] dbMask = mgf1.generateMask(seed, publicKey.getModulus().bitLength() / 8 - lHash.length - 1);// DB和dbMask做异或运算生成maskedDBbyte[] maskedDB = new BigInteger(DB).xor(new BigInteger(dbMask)).toByteArray();byte[] seedMask = mgf1.generateMask(maskedDB, lHash.length);// seed和seedMask做异或运算生成maskedSeedbyte[] maskedSeed = new BigInteger(seed).xor(new BigInteger(seedMask)).toByteArray();byte[] EM = new byte[publicKey.getModulus().bitLength() / 8];EM[0] = 0;System.arraycopy(maskedSeed, 0, EM, 1, maskedSeed.length);System.arraycopy(maskedDB, 0, EM, maskedSeed.length + 1,maskedDB.length);return EM;}/** * @param key */public static void setPublicKey(String key){RSA2048Utils.key = key;}}




0 0
原创粉丝点击