實際項目中,發現前端在生成公鑰對象的時候並不是使用這種方式,而是通過對應的模數跟質數來構造公鑰對象的,這樣的話,需要進一步將生成的公鑰取出對應的模數和質數。openssl、java api都可以將質數跟模數取出來。
正常生成公私鑰如下:
1.通過openssl工具取出模數和質數
命令行使用 openssl rsa -in priKey.pem -noout -text,得到下圖中的modules以及publicExponent
這里我們都取十六進制的。這樣對應的模數(前面的00去掉即可)跟質數就出來了。
2.通過java api取對應的模數跟質數
package com.wangjinxiang.genkey.util; import java.security.interfaces.RSAPublicKey; import org.apache.commons.codec.binary.Base64; public class KeyModulesAndExponentUtil { private static String PUBKEY_TEXT = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxdHDlJrjF+anpWRbiLuN2Hu9oPaABcVKAJSCq3UEreIn33ldx645l+9RDat6THqJEeTjRt9orogXwpAeFkDqje0YFjTu4v3eyLnkGjg3oDozYCoY9c7vfQ/BMw3X+2Wy0lYpRg23qis0lWB/ZdoVnj6SP0fcXBiqJSk+/deZNVreUvozl0X1o17EyJsKGJd2Uk0ltC3DfRve0TK1TJp4pssEDLRqFPAVJSJjFEe2lr6IUKDlv9ArPRZXh67zxxe1t/qW+tJSJjhaQKFLwpYVmpNnPNuYJ7gLqLPxDiqosFVJK0q3On2IFbviaXMhwGv85GD2Exlmn9KDW4p1box6QQIDAQAB"; public static void getModulesAndExponent() throws Exception { try { // 解密由base64編碼的公鑰,並構造X509EncodedKeySpec對象 java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec( Base64.decodeBase64(PUBKEY_TEXT)); // RSA算法 java.security.KeyFactory keyFactory = java.security.KeyFactory.getInstance("RSA"); // 取公鑰匙對象 RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(bobPubKeySpec); System.out.println("modules: 0x" + pubKey.getModulus().toString(16)); System.out.println("publicExponent: 0x" + pubKey.getPublicExponent().toString(16)); }catch(Exception e) { throw e; } } public static void main(String[] args) { try { KeyModulesAndExponentUtil.getModulesAndExponent(); } catch (Exception e) { e.printStackTrace(); } } }
打印出來的結構跟使用openssl工具是一樣的。
至此,這兩種方法都可以正確取出模數(modules)和質數(publicExponent),這時,就可以把獲得的模數和質數給到前端了,我也可以用獲得的模數和質數模擬前端加密處理了。