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);
    }
}