import java.util.Base64; import java.math.BigInteger; import java.io.ByteArrayInputStream; public class KeyAnalyzer { public static void main(String[] args) { String privateKeyBase64 = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCcxAwrhZF+izz1gxQKOr4jnC05obIBHbl0DzHOcd4CaaDV7Kv1NRJKi33JhdDsW4JGgu16e5Rtzq1VzU5VWz5EKgGL46maOFwCkngJUTP/LC3JVf/wtJmYCm8xNE8C7GNNIqKzYEvUOEfXqagpVvVrGsQ9FpzFp2rP9hBmHY3yizVyPX/uT9S+af5TRxiaItj3SSJGgloaEMrnKOpb/EH7JwPSS0liAyT/NxPfOyyZHc22AvaAIOE5y+0PMUIKPuIdfpOrej3LVpO1Arc2hSgmdB+YIPSiBVYPXa6AuAmil9mpbtSikQJ7Uu7lX4JyTW4QxQ06rPFKnFWVKkzivAElAgMBAAECggEAJd0AJ37iTlMpDQ90xqe7hvRQxAu256gbQ9nrqLY97g0/KIw6WEZSPakFX6gvdvb/NzKmUyAIEKGLoh6tXdZk6qfOqc/6BeK47nIcBfwT9/zerjNUVvn34w4aHyNINieMMHQ+Id8PUZmqWH+Euz9ilVTosuyEPwUZulLvUQqwXzU5VnwVghURbUhDd+ecBJACWgemRun6d5241PQXNYAdH1k7cETd8GfIi3qclhhJrxi7tu5tq4YGCXQIoz7HCLim7GIvT0M+FRgSw2EOrHnAQNFeQ/vQbP71ttLoTxehL6Se9dfWrV5OI+Y/T7vR2F84Qt0iNbaxyJGir7siKDFIwQKBgQDXDzinx3/TasplM78pR/0CtuuKr1Ch02LOPrTosJ1qf1OohxQThowhOTxMsBlgYSKu9s1QRffUUXEqYXxd2B6lzDKfggwO6U2XxIcxWeNow0xoFfqcXYSg7Ga2sCr9uhdwxIdFQNF7SNBpT8ht4fJrRX6mWY1nHybpyTDQ4xoQNQKBgQC6m+yiOoi5JD3zVSSJq/iq5DJPA5B4aoP+t5u9lp2Q7iVO0QI5ilBlEKGE4VOU0glnXlDTfuqEYooMY85ekl4WGb3AOT0PhLL2i+gO2nlWBzf4HPzB/hibjfyPyniRM03cHkG3HXucL7Sne6FwERcfjEqjUd2cdP1l89PNrq4rMQKBgQCMmjABSWYh8/y1I5rEQ4OAJdVjC3GdC1Xa35ZpVybjvLEWSpHunhW5lvD8dllw8LC7UTI0XDpGPqTM/4VO2YBYB2PFc0Gs8g0/v0ZgFpOeJ6kpl80MM/wFNemFYTIKRoMSv/psZY9PmfBgGcBBTuquBXZjDcNr+yr2yAm5V/DvTQKBgHqRi94KoF8q5N39IKCkqhJlDH5FkxDktYoKw2rFkPzuzuZz9gghRyj6wXxsG9/2DWMt2dzw0czehFoa/CO188KEadPmRKr6uCmkP2nyKhxNZX+8WnB5G2Sg4DD6BjMpBYz8+qDx5ozx8LDJTYI0V4HLPgMD9JGdbgsXGhlREOkhAoGALr6IQOXnviWNAhCdc7rrsaMLMPbLZ1wqzWtQUG1JxDobbpzEP4CW/mvW5pMn58mSBg5qbXhyDI4fFP0CPb98QIz2tGnIzYyFzdKmF5Z1N7X1OF9O+tsSqASoBZzTqB4fr/o4mz0s9JCeriBR2LWjsbsDU13DTLsfQpWbtOnIy70="; System.out.println("========== 密钥分析开始 =========="); System.out.println("密钥长度: " + privateKeyBase64.length()); byte[] keyBytes = Base64.getDecoder().decode(privateKeyBase64); System.out.println("解码后长度: " + keyBytes.length + " bytes"); // 打印前30字节 System.out.print("前30字节(hex): "); for (int i = 0; i < 30 && i < keyBytes.length; i++) { System.out.printf("%02X ", keyBytes[i]); } System.out.println(); // 解析ASN.1结构 try { parseASN1(keyBytes); } catch (Exception e) { System.out.println("解析失败: " + e.getMessage()); e.printStackTrace(); } } static void parseASN1(byte[] keyBytes) throws Exception { ByteArrayInputStream bis = new ByteArrayInputStream(keyBytes); // 读取SEQUENCE int tag = bis.read(); System.out.println("第一个tag: 0x" + Integer.toHexString(tag)); if (tag == 0x30) { System.out.println("这是SEQUENCE"); // 读取长度 int len = readASN1Length(bis); System.out.println("SEQUENCE长度: " + len); // 检查下一个tag int nextTag = bis.read(); System.out.println("下一个tag: 0x" + Integer.toHexString(nextTag)); if (nextTag == 0x02) { // INTEGER int intLen = readASN1Length(bis); byte[] versionBytes = new byte[intLen]; bis.read(versionBytes); int version = new BigInteger(versionBytes).intValue(); System.out.println("版本INTEGER值: " + version); // 检查这是PKCS#8还是PKCS#1 // PKCS#8: version=0后是SEQUENCE(算法标识符) // PKCS#1: version=0后是INTEGER(modulus) int afterVersionTag = bis.read(); System.out.println("版本后的tag: 0x" + Integer.toHexString(afterVersionTag)); if (afterVersionTag == 0x30) { System.out.println(">>> 这是PKCS#8格式 (version后是SEQUENCE)"); // 解析PKCS#8 // AlgorithmIdentifier: SEQUENCE { OID, NULL } int algLen = readASN1Length(bis); System.out.println("AlgorithmIdentifier长度: " + algLen); // 跳过AlgorithmIdentifier内容 byte[] algBytes = new byte[algLen]; bis.read(algBytes); // 打印OID System.out.print("OID bytes: "); for (int i = 0; i < algBytes.length; i++) { System.out.printf("%02X ", algBytes[i]); } System.out.println(); // 下一个应该是OCTET STRING (包含私钥) int octetTag = bis.read(); System.out.println("下一个tag: 0x" + Integer.toHexString(octetTag)); if (octetTag == 0x04) { System.out.println("这是OCTET STRING (包含私钥数据)"); int octetLen = readASN1Length(bis); System.out.println("OCTET STRING长度: " + octetLen); // OCTET STRING内容是PKCS#1私钥 byte[] pkcs1Bytes = new byte[octetLen]; bis.read(pkcs1Bytes); System.out.print("PKCS#1私钥前20字节: "); for (int i = 0; i < 20; i++) { System.out.printf("%02X ", pkcs1Bytes[i]); } System.out.println(); // 解析PKCS#1私钥 ByteArrayInputStream pkcs1Stream = new ByteArrayInputStream(pkcs1Bytes); int pkcs1Tag = pkcs1Stream.read(); System.out.println("PKCS#1第一个tag: 0x" + Integer.toHexString(pkcs1Tag)); if (pkcs1Tag == 0x30) { int pkcs1Len = readASN1Length(pkcs1Stream); System.out.println("PKCS#1 SEQUENCE长度: " + pkcs1Len); // version int vTag = pkcs1Stream.read(); int vLen = readASN1Length(pkcs1Stream); byte[] vBytes = new byte[vLen]; pkcs1Stream.read(vBytes); System.out.println("PKCS#1版本: " + new BigInteger(vBytes)); // 解析私钥参数 parsePKCS1(pkcs1Stream); } } } else if (afterVersionTag == 0x02) { System.out.println(">>> 这是PKCS#1格式 (version后是INTEGER)"); // 继续解析PKCS#1 parsePKCS1(bis); } else { System.out.println(">>> 未知格式 (tag: 0x" + Integer.toHexString(afterVersionTag) + ")"); } } } } static void parsePKCS1(ByteArrayInputStream bis) throws Exception { System.out.println("\n========== 解析PKCS#1私钥参数 =========="); // modulus BigInteger modulus = readASN1Integer(bis); System.out.println("modulus长度: " + modulus.bitLength() + " bits"); // publicExponent BigInteger publicExponent = readASN1Integer(bis); System.out.println("publicExponent: " + publicExponent); // privateExponent BigInteger privateExponent = readASN1Integer(bis); System.out.println("privateExponent长度: " + privateExponent.bitLength() + " bits"); // prime1 BigInteger prime1 = readASN1Integer(bis); System.out.println("prime1长度: " + prime1.bitLength() + " bits"); // prime2 BigInteger prime2 = readASN1Integer(bis); System.out.println("prime2长度: " + prime2.bitLength() + " bits"); // 验证 prime1 * prime2 == modulus BigInteger calculatedModulus = prime1.multiply(prime2); boolean valid = calculatedModulus.equals(modulus); System.out.println("\n验证 prime1 * prime2 == modulus: " + valid); if (!valid) { System.out.println(">>> 密钥数学关系不正确!这是无效的RSA私钥"); System.out.println("计算得到的modulus长度: " + calculatedModulus.bitLength() + " bits"); } // exponent1 BigInteger exponent1 = readASN1Integer(bis); System.out.println("exponent1长度: " + exponent1.bitLength() + " bits"); // exponent2 BigInteger exponent2 = readASN1Integer(bis); System.out.println("exponent2长度: " + exponent2.bitLength() + " bits"); // coefficient BigInteger coefficient = readASN1Integer(bis); System.out.println("coefficient长度: " + coefficient.bitLength() + " bits"); System.out.println("\n========== 解析完成 =========="); } static int readASN1Length(ByteArrayInputStream bis) throws Exception { int firstByte = bis.read(); if ((firstByte & 0x80) == 0) { return firstByte; } int numBytes = firstByte & 0x7F; int length = 0; for (int i = 0; i < numBytes; i++) { length = (length << 8) | (bis.read() & 0xFF); } return length; } static BigInteger readASN1Integer(ByteArrayInputStream bis) throws Exception { int tag = bis.read(); if (tag != 0x02) throw new Exception("期望INTEGER tag: 0x02, 实际: 0x" + Integer.toHexString(tag)); int len = readASN1Length(bis); byte[] data = new byte[len]; bis.read(data); return new BigInteger(1, data); } }