@@ -119,14 +119,28 @@ public static KeyPair readPrivateKey(final Type type, final PrivateKeyInfo keyIn
119119 exp1 .getValue (), exp2 .getValue (), crtCoef .getValue ());
120120 break ;
121121 case DSA :
122- seq = (ASN1Sequence ) keyInfo .parsePrivateKey ();
123- ASN1Integer p = (ASN1Integer ) seq .getObjectAt (1 );
124- ASN1Integer q = (ASN1Integer ) seq .getObjectAt (2 );
125- ASN1Integer g = (ASN1Integer ) seq .getObjectAt (3 );
126- ASN1Integer y = (ASN1Integer ) seq .getObjectAt (4 );
127- ASN1Integer x = (ASN1Integer ) seq .getObjectAt (5 );
128- privSpec = new DSAPrivateKeySpec (x .getValue (), p .getValue (), q .getValue (), g .getValue ());
129- pubSpec = new DSAPublicKeySpec (y .getValue (), p .getValue (), q .getValue (), g .getValue ());
122+ final ASN1Encodable parsedDSAKey = keyInfo .parsePrivateKey ();
123+ if (parsedDSAKey instanceof ASN1Integer ) {
124+ // PKCS#8 format: private key is just x (INTEGER), params in AlgorithmIdentifier
125+ final BigInteger xVal = ((ASN1Integer ) parsedDSAKey ).getValue ();
126+ final DSAParameter dsaParam = DSAParameter .getInstance (keyInfo .getPrivateKeyAlgorithm ().getParameters ());
127+ final BigInteger pVal = dsaParam .getP ();
128+ final BigInteger qVal = dsaParam .getQ ();
129+ final BigInteger gVal = dsaParam .getG ();
130+ final BigInteger yVal = gVal .modPow (xVal , pVal );
131+ privSpec = new DSAPrivateKeySpec (xVal , pVal , qVal , gVal );
132+ pubSpec = new DSAPublicKeySpec (yVal , pVal , qVal , gVal );
133+ } else {
134+ // Traditional "DSA PRIVATE KEY" format: SEQUENCE { version, p, q, g, y, x }
135+ seq = (ASN1Sequence ) parsedDSAKey ;
136+ ASN1Integer p = (ASN1Integer ) seq .getObjectAt (1 );
137+ ASN1Integer q = (ASN1Integer ) seq .getObjectAt (2 );
138+ ASN1Integer g = (ASN1Integer ) seq .getObjectAt (3 );
139+ ASN1Integer y = (ASN1Integer ) seq .getObjectAt (4 );
140+ ASN1Integer x = (ASN1Integer ) seq .getObjectAt (5 );
141+ privSpec = new DSAPrivateKeySpec (x .getValue (), p .getValue (), q .getValue (), g .getValue ());
142+ pubSpec = new DSAPublicKeySpec (y .getValue (), p .getValue (), q .getValue (), g .getValue ());
143+ }
130144 break ;
131145 case EC :
132146 return readECPrivateKey (SecurityHelper .getKeyFactory ("EC" ), keyInfo );
@@ -142,9 +156,8 @@ public static PublicKey readPublicKey(final byte[] input) throws IOException {
142156 // Try PEM first
143157 try (Reader in = new InputStreamReader (new ByteArrayInputStream (input ))) {
144158 Object pemObject = new PEMParser (in ).readObject ();
145- if (pemObject != null ) {
146- SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo .getInstance (pemObject );
147- return new JcaPEMKeyConverter ().getPublicKey (publicKeyInfo );
159+ if (pemObject instanceof SubjectPublicKeyInfo ) {
160+ return new JcaPEMKeyConverter ().getPublicKey ((SubjectPublicKeyInfo ) pemObject );
148161 }
149162 }
150163 // Fall back to DER-encoded SubjectPublicKeyInfo
@@ -335,7 +348,8 @@ public static ASN1Sequence toASN1Primitive(final RSAPublicKey publicKey) {
335348 return new DERSequence (vec );
336349 }
337350
338- public static byte [] toDerDSAKey (DSAPublicKey pubKey , DSAPrivateKey privKey ) throws IOException {
351+ public static byte [] toDerDSAKey (DSAPublicKey pubKey , DSAPrivateKey privKey )
352+ throws IOException , IllegalArgumentException {
339353 if ( pubKey != null && privKey == null ) {
340354 return toDerDSAPublicKey (pubKey );
341355 }
0 commit comments