把Java生成的RSA公鑰、私鑰轉換成.NET使用的XML格式

FrankYou發表於2015-07-21

測試程式碼:

PrivateKey privateKey=RSAUtils.getRSAPrivateKeyBybase64(savePrivateKey);
PublicKey publicKey=RSAUtils.getRSAPublidKeyBybase64(savePublicKey);
String publicKeyXml = getRSAPublicKeyAsNetFormat(publicKey.getEncoded());
String privateKeyXml = getRSAPrivateKeyAsNetFormat(privateKey.getEncoded());
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
 1  private static String getRSAPrivateKeyAsNetFormat(byte[] encodedPrivkey) {
 2         try {
 3             StringBuffer buff = new StringBuffer(1024);
 4 
 5             PKCS8EncodedKeySpec pvkKeySpec = new PKCS8EncodedKeySpec(
 6                     encodedPrivkey);
 7             KeyFactory keyFactory = KeyFactory.getInstance("RSA");
 8             RSAPrivateCrtKey pvkKey = (RSAPrivateCrtKey) keyFactory
 9                     .generatePrivate(pvkKeySpec);
10 
11             buff.append("<RSAKeyValue>");
12             buff.append("<Modulus>"
13                     + CodeUtils.base64Encode(removeMSZero(pvkKey.getModulus().toByteArray()))
14                     + "</Modulus>");
15 
16             buff.append("<Exponent>"
17                     + CodeUtils.base64Encode(removeMSZero(pvkKey.getPublicExponent()
18                     .toByteArray())) + "</Exponent>");
19 
20             buff.append("<P>"
21                     + CodeUtils.base64Encode(removeMSZero(pvkKey.getPrimeP().toByteArray()))
22                     + "</P>");
23 
24             buff.append("<Q>"
25                     + CodeUtils.base64Encode(removeMSZero(pvkKey.getPrimeQ().toByteArray()))
26                     + "</Q>");
27 
28             buff.append("<DP>"
29                     + CodeUtils.base64Encode(removeMSZero(pvkKey.getPrimeExponentP()
30                     .toByteArray())) + "</DP>");
31 
32             buff.append("<DQ>"
33                     + CodeUtils.base64Encode(removeMSZero(pvkKey.getPrimeExponentQ()
34                     .toByteArray())) + "</DQ>");
35 
36             buff.append("<InverseQ>"
37                     + CodeUtils.base64Encode(removeMSZero(pvkKey.getCrtCoefficient()
38                     .toByteArray())) + "</InverseQ>");
39 
40             buff.append("<D>"
41                     + CodeUtils.base64Encode(removeMSZero(pvkKey.getPrivateExponent()
42                     .toByteArray())) + "</D>");
43             buff.append("</RSAKeyValue>");
44 
45             return buff.toString().replaceAll("[ \t\n\r]", "");
46         } catch (Exception e) {
47             System.err.println(e);
48             return null;
49         }
50     }
51 
52     private static String getRSAPublicKeyAsNetFormat(byte[] encodedPublicKey) {
53         try {
54 
55             KeyFactory keyFactory = KeyFactory.getInstance("RSA");
56             RSAPublicKey pukKey = (RSAPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(encodedPublicKey));
57 
58             StringBuffer buff = new StringBuffer(1024);
59             buff.append("<RSAKeyValue>");
60             buff.append("<Modulus>"
61                     + CodeUtils.base64Encode(removeMSZero(pukKey.getModulus().toByteArray()))
62                     + "</Modulus>");
63             buff.append("<Exponent>"
64                     + CodeUtils.base64Encode(removeMSZero(pukKey.getPublicExponent().toByteArray())) + "</Exponent>");
65             buff.append("</RSAKeyValue>");
11


66             return buff.toString().replaceAll("[ \t\n\r]", "");
67         } catch (Exception e) {
68             System.err.println(e);
69             return null;
70         }
71     }
    private static byte[] removeMSZero(byte[] data) {
        byte[] data1;
        int len = data.length;
        if (data[0] == 0) {
            data1 = new byte[data.length - 1];
            System.arraycopy(data, 1, data1, 0, len - 1);
        } else
            data1 = data;

        return data1;
    }

 RSAUtils.java

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.union.pufa;

import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAKeyGenParameterSpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class RSAUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(RSAUtils.class);
    private static final String ALGORITHOM = "RSA";
    private static final Provider DEFAULT_PROVIDER = new BouncyCastleProvider();
    private static final String SIGNATURE_MD5WITHRSA = "MD5withRSA";
    private static final String SIGNATURE_SHA1WITHRSA = "SHA1withRSA";
    private static final String SIGNATURE_ALGORITHM_DEFAULT = "NONEwithRSA";
    private static final String CIPHER_TRANSFORMATION_DEFAULT = "RSA/ECB/PKCS1Padding";
    private static final String HASHID_SHA1 = "01";
    private static final String HASHID_MD5 = "02";
    private static KeyPairGenerator keyPairGen = null;
    private static KeyFactory keyFactory = null;

    static {
        try {
            keyPairGen = KeyPairGenerator.getInstance("RSA", DEFAULT_PROVIDER);
            keyFactory = KeyFactory.getInstance("RSA", DEFAULT_PROVIDER);
        } catch (NoSuchAlgorithmException var1) {
            LOGGER.error(var1.getMessage());
        }

    }

    private RSAUtils() {
    }

    public static synchronized KeyPair generateRSAKeyPair(int keysize, BigInteger publicExponent) {
        try {
            keyPairGen.initialize(new RSAKeyGenParameterSpec(keysize, publicExponent), new SecureRandom());
            return keyPairGen.generateKeyPair();
        } catch (Exception var3) {
            LOGGER.error("生成模長 =" + keysize + ",指數=" + publicExponent + "的RSA金鑰對失敗", var3);
            return null;
        }
    }

    public static PrivateKey getRSAPrivateKey(String hexModulus, String hexPrivateExponent) {
        if(!StringUtils.isBlank(hexModulus) && !StringUtils.isBlank(hexPrivateExponent)) {
            BigInteger mbig = new BigInteger(hexModulus, 16);
            BigInteger ebig = new BigInteger(hexPrivateExponent, 16);
            RSAPrivateKeySpec prispec = new RSAPrivateKeySpec(mbig, ebig);

            try {
                return keyFactory.generatePrivate(prispec);
            } catch (InvalidKeySpecException var6) {
                LOGGER.error("hexModulus or hexPrivateExponent value is invalid. return null(RSAPrivateKey).");
                return null;
            }
        } else {
            if(LOGGER.isDebugEnabled()) {
                LOGGER.debug("hexModulus and hexPrivateExponent cannot be empty. RSAPrivateKey value is null to return.");
            }

            return null;
        }
    }

    public static PublicKey getRSAPublidKey(String hexModulus, String hexPublicExponent) {
        if(!StringUtils.isBlank(hexModulus) && !StringUtils.isBlank(hexPublicExponent)) {
            BigInteger mbig = new BigInteger(hexModulus, 16);
            BigInteger ebig = new BigInteger(hexPublicExponent, 16);
            RSAPublicKeySpec pubspec = new RSAPublicKeySpec(mbig, ebig);

            try {
                return keyFactory.generatePublic(pubspec);
            } catch (InvalidKeySpecException var6) {
                LOGGER.error("hexModulus or hexPublicExponent value is invalid. return null(RSAPublicKey).");
                return null;
            }
        } else {
            if(LOGGER.isDebugEnabled()) {
                LOGGER.debug("hexModulus and hexPublicExponent cannot be empty. return null(RSAPublicKey).");
            }

            return null;
        }
    }

    public static String getBase64CodeKey(Key key) {
        return CodeUtils.base64Encode(key.getEncoded());
    }

    public static String getNakedPublicKey(RSAPublicKey key) {
        return key.getModulus().toString(16).toUpperCase();
    }

    private static byte[] getAsn1Len(int len) {
        int ret = false;
        byte[] buff = new byte[10];
        byte[] asn1Len = (byte[])null;
        if(len > '\uffff') {
            return null;
        } else {
            byte ret;
            if(len > 255) {
                buff[0] = -126;
                buff[1] = (byte)((len & '\uff00') >> 8);
                buff[2] = (byte)(len & 255);
                ret = 3;
            } else if((len & 128) != 0) {
                buff[0] = -127;
                buff[1] = (byte)len;
                ret = 2;
            } else {
                buff[0] = (byte)len;
                ret = 1;
            }

            asn1Len = new byte[ret];
            System.arraycopy(buff, 0, asn1Len, 0, ret);
            return asn1Len;
        }
    }

    public static byte[] getDerPK(byte[] pkModule, byte[] exp) {
        byte[] buff = new byte[4096];
        byte[] tbuff = new byte[4096];
        byte[] tmp = (byte[])null;
        byte[] derPK = (byte[])null;
        int offset = false;
        int len = false;
        int lenOfPkModule = pkModule.length;
        int lenOfExp = exp.length;
        if(pkModule != null && exp != null) {
            int offset = 0;
            tbuff[offset] = 2;
            int offset = offset + 1;
            tmp = getAsn1Len(lenOfPkModule + 1);
            System.arraycopy(tmp, 0, tbuff, offset, tmp.length);
            offset += tmp.length;
            tbuff[offset] = 0;
            ++offset;
            System.arraycopy(pkModule, 0, tbuff, offset, lenOfPkModule);
            offset += lenOfPkModule;
            tbuff[offset] = 2;
            ++offset;
            tmp = getAsn1Len(lenOfExp);
            System.arraycopy(tmp, 0, tbuff, offset, tmp.length);
            offset += tmp.length;
            System.arraycopy(exp, 0, tbuff, offset, lenOfExp);
            offset += lenOfExp;
            int len = offset;
            offset = 0;
            buff[offset] = 48;
            offset = offset + 1;
            tmp = getAsn1Len(len);
            System.arraycopy(tmp, 0, buff, offset, tmp.length);
            offset += tmp.length;
            System.arraycopy(tbuff, 0, buff, offset, len);
            offset += len;
            derPK = new byte[offset];
            System.arraycopy(buff, 0, derPK, 0, offset);
            return derPK;
        } else {
            return null;
        }
    }

    public static String getDerPKWithAscHex(String pkModule, String exp) {
        return pkModule != null && exp != null?CodeUtils.byte2hex(getDerPK(CodeUtils.hex2byte(pkModule), CodeUtils.hex2byte(exp))):null;
    }

    public static PublicKey getPKfromDerPK(String racalPK) {
        byte[] racalPKStr = (byte[])null;
        if(racalPK == null) {
            return null;
        } else {
            racalPKStr = CodeUtils.hex2byte(racalPK);
            int offset = 0;
            if(racalPKStr[offset] != 48) {
                return null;
            } else {
                int offset = offset + 1;
                int i;
                int lenOfNextPart;
                int bitsOfLenFlag;
                if((racalPKStr[offset] & 255) <= 128) {
                    lenOfNextPart = racalPKStr[offset] & 255;
                    ++offset;
                } else {
                    bitsOfLenFlag = (racalPKStr[offset] & 255) - 128;
                    ++offset;
                    i = 0;

                    for(lenOfNextPart = 0; i < bitsOfLenFlag; ++offset) {
                        lenOfNextPart += racalPKStr[offset] & 255;
                        ++i;
                    }
                }

                if((racalPKStr[offset] & 255) != 2) {
                    return null;
                } else {
                    ++offset;
                    --lenOfNextPart;
                    int lenOfPK = false;
                    int lenOfPK;
                    if((racalPKStr[offset] & 255) <= 128) {
                        lenOfPK = racalPKStr[offset] & 255;
                        ++offset;
                    } else {
                        bitsOfLenFlag = (racalPKStr[offset] & 255) - 128;
                        ++offset;
                        i = 0;

                        for(lenOfPK = 0; i < bitsOfLenFlag; ++offset) {
                            lenOfPK += racalPKStr[offset] & 255;
                            ++i;
                        }
                    }

                    while(lenOfPK % 8 != 0) {
                        if((racalPKStr[offset] & 255) != 0) {
                            return null;
                        }

                        ++offset;
                        --lenOfPK;
                    }

                    byte[] LPk = new byte[lenOfPK];
                    System.arraycopy(racalPKStr, offset, LPk, 0, lenOfPK);
                    String pk = CodeUtils.byte2hex(LPk);
                    offset += lenOfPK;
                    int lenOfEval = false;
                    if(racalPKStr[offset] != 2) {
                        return null;
                    } else {
                        ++offset;
                        int lenOfEval = racalPKStr[offset];
                        ++offset;
                        byte[] LPkEval = new byte[lenOfEval];
                        System.arraycopy(racalPKStr, offset, LPkEval, 0, lenOfEval);
                        return getRSAPublidKey(pk, CodeUtils.byte2hex(LPkEval));
                    }
                }
            }
        }
    }

    public static RSAPublicKey getRSAPublidKeyBybase64(String base64s) {
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(CodeUtils.base64Decode(base64s));
        RSAPublicKey publicKey = null;

        try {
            publicKey = (RSAPublicKey)keyFactory.generatePublic(keySpec);
        } catch (InvalidKeySpecException var4) {
            LOGGER.error("base64編碼=" + base64s + "轉RSA公鑰失敗", var4);
        }

        return publicKey;
    }

    public static RSAPrivateKey getRSAPrivateKeyBybase64(String base64s) {
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(CodeUtils.base64Decode(base64s));
        RSAPrivateKey privateKey = null;

        try {
            privateKey = (RSAPrivateKey)keyFactory.generatePrivate(keySpec);
        } catch (InvalidKeySpecException var4) {
            LOGGER.error("base64編碼=" + base64s + "轉RSA私鑰失敗", var4);
        }

        return privateKey;
    }

    public static byte[] encrypt(Key key, byte[] data) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", DEFAULT_PROVIDER);
        cipher.init(1, key);
        return cipher.doFinal(data);
    }

    public static byte[] decrypt(Key key, byte[] data) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", DEFAULT_PROVIDER);
        cipher.init(2, key);
        return cipher.doFinal(data);
    }

    public static String encryptString(Key key, String plaintext) {
        if(key != null && plaintext != null) {
            byte[] data = plaintext.getBytes();

            try {
                byte[] en_data = encrypt(key, data);
                return new String(Hex.encodeHex(en_data));
            } catch (Exception var4) {
                LOGGER.error(var4.getCause().getMessage());
                return null;
            }
        } else {
            return null;
        }
    }

    public static String encryptStr4essc(Key key, String plaintext, String accNo, String encType) {
        if(key != null && plaintext != null) {
            if("1".equals(encType)) {
                plaintext = CodeUtils.paddingRightStr(plaintext, 'F', 16);
            } else if("0".equals(encType)) {
                plaintext = CodeUtils.asc2ascInt2hexasc(CodeUtils.paddingRightStr(plaintext, 'F', 16));
            }

            byte[] data = CodeUtils.hex2byte(plaintext);

            try {
                byte[] en_data = encrypt(key, data);
                return (new String(Hex.encodeHex(en_data))).toUpperCase();
            } catch (Exception var6) {
                LOGGER.error(var6.getCause().getMessage());
                return null;
            }
        } else {
            return null;
        }
    }

    public static String decryptString(Key key, String encrypttext) {
        if(key != null && !StringUtils.isBlank(encrypttext)) {
            try {
                byte[] en_data = Hex.decodeHex(encrypttext.toCharArray());
                byte[] data = decrypt(key, en_data);
                return new String(data);
            } catch (Exception var4) {
                LOGGER.error(String.format("\"%s\" Decryption failed. Cause: %s", new Object[]{encrypttext, var4.getCause().getMessage()}));
                return null;
            }
        } else {
            return null;
        }
    }

    public static String sign(RSAPrivateKey privatekey, String dataFillMode, String hashID, String data) throws Exception {
        Signature signature = Signature.getInstance("NONEwithRSA");
        if("01".equals(hashID)) {
            data = CodeUtils.sha1String(data).toUpperCase();
        } else if("02".equals(hashID)) {
            data = CodeUtils.md5String(data).toUpperCase();
        }

        signature.initSign(privatekey);
        signature.update(data.getBytes());
        return CodeUtils.byte2hex(signature.sign()).toUpperCase();
    }

    public static boolean verifySign(PublicKey publicKey, String dataFillMode, String hashID, String data, String sign) throws Exception {
        Signature signature = Signature.getInstance("NONEwithRSA");
        if("01".equals(hashID)) {
            data = CodeUtils.sha1String(data).toUpperCase();
        } else if("02".equals(hashID)) {
            data = CodeUtils.md5String(data).toUpperCase();
        }

        signature.initVerify(publicKey);
        signature.update(data.getBytes());
        return signature.verify(CodeUtils.hex2byte(sign.toUpperCase()));
    }
}

 

相關文章