forked from ZZMarquis/gmhelper
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
142 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package org.zz.gmhelper.cert; | ||
|
||
import org.bouncycastle.asn1.ASN1Encodable; | ||
import org.bouncycastle.asn1.ASN1Encoding; | ||
import org.bouncycastle.asn1.ASN1Primitive; | ||
import org.bouncycastle.asn1.DERBitString; | ||
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; | ||
import org.bouncycastle.asn1.x509.AlgorithmIdentifier; | ||
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; | ||
import org.bouncycastle.asn1.x9.X962Parameters; | ||
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; | ||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; | ||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; | ||
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; | ||
import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; | ||
import org.bouncycastle.jce.provider.BouncyCastleProvider; | ||
import org.zz.gmhelper.BCECUtil; | ||
|
||
import java.io.IOException; | ||
import java.security.spec.ECParameterSpec; | ||
|
||
public class SM2PrivateKey extends BCECPrivateKey { | ||
private transient DERBitString sm2PublicKey; | ||
private boolean withCompression; | ||
|
||
public SM2PrivateKey(BCECPrivateKey privateKey, BCECPublicKey publicKey) { | ||
super(privateKey.getAlgorithm(), privateKey); | ||
this.sm2PublicKey = getSM2PublicKeyDetails(new SM2PublicKey(publicKey.getAlgorithm(), publicKey)); | ||
this.withCompression = false; | ||
} | ||
|
||
@Override | ||
public void setPointFormat(String style) | ||
{ | ||
withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); | ||
} | ||
|
||
/** | ||
* Return a PKCS8 representation of the key. The sequence returned | ||
* represents a full PrivateKeyInfo object. | ||
* | ||
* @return a PKCS8 representation of the key. | ||
*/ | ||
@Override | ||
public byte[] getEncoded() | ||
{ | ||
ECParameterSpec ecSpec = getParams(); | ||
ProviderConfiguration configuration = BouncyCastleProvider.CONFIGURATION; | ||
ASN1Encodable params = SM2PublicKey.ID_SM2_PUBKEY_PARAM; | ||
|
||
int orderBitLength; | ||
if (ecSpec == null) | ||
{ | ||
orderBitLength = ECUtil.getOrderBitLength(configuration, null, this.getS()); | ||
} | ||
else | ||
{ | ||
orderBitLength = ECUtil.getOrderBitLength(configuration, ecSpec.getOrder(), this.getS()); | ||
} | ||
|
||
PrivateKeyInfo info; | ||
org.bouncycastle.asn1.sec.ECPrivateKey keyStructure; | ||
|
||
if (sm2PublicKey != null) | ||
{ | ||
keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), sm2PublicKey, params); | ||
} | ||
else | ||
{ | ||
keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params); | ||
} | ||
|
||
try | ||
{ | ||
info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), keyStructure); | ||
|
||
return info.getEncoded(ASN1Encoding.DER); | ||
} | ||
catch (IOException e) | ||
{ | ||
return null; | ||
} | ||
} | ||
|
||
private DERBitString getSM2PublicKeyDetails(SM2PublicKey pub) | ||
{ | ||
try | ||
{ | ||
SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded())); | ||
|
||
return info.getPublicKeyData(); | ||
} | ||
catch (IOException e) | ||
{ // should never happen | ||
return null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
src/test/java/org/zz/gmhelper/cert/test/SM2PrivateKeyTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package org.zz.gmhelper.cert.test; | ||
|
||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; | ||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; | ||
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; | ||
import org.junit.Assert; | ||
import org.junit.Test; | ||
import org.zz.gmhelper.SM2Util; | ||
import org.zz.gmhelper.cert.SM2PrivateKey; | ||
import org.zz.gmhelper.cert.SM2PublicKey; | ||
|
||
import java.security.InvalidAlgorithmParameterException; | ||
import java.security.KeyPair; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.NoSuchProviderException; | ||
|
||
public class SM2PrivateKeyTest { | ||
@Test | ||
public void testEncoded() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { | ||
KeyPair keyPair = SM2Util.generateKeyPair(); | ||
BCECPrivateKey privateKey = (BCECPrivateKey) keyPair.getPrivate(); | ||
BCECPublicKey publicKey = (BCECPublicKey) keyPair.getPublic(); | ||
SM2PublicKey sm2PublicKey = new SM2PublicKey(publicKey.getAlgorithm(), publicKey); | ||
SM2PrivateKey sm2PrivateKey1 = new SM2PrivateKey(privateKey, publicKey); | ||
SM2PrivateKey sm2PrivateKey2 = new SM2PrivateKey(privateKey, sm2PublicKey); | ||
String nativePriDER = ByteUtils.toHexString(privateKey.getEncoded()); | ||
String sm2PriDER1 = ByteUtils.toHexString(sm2PrivateKey1.getEncoded()); | ||
String sm2PriDER2 = ByteUtils.toHexString(sm2PrivateKey2.getEncoded()); | ||
if (nativePriDER.equalsIgnoreCase(sm2PriDER1)) { | ||
Assert.fail(); | ||
} | ||
if (!sm2PriDER1.equalsIgnoreCase(sm2PriDER2)) { | ||
Assert.fail(); | ||
} | ||
System.out.println("Native EC Private Key DER:\n" + nativePriDER.toUpperCase()); | ||
System.out.println("SM2 EC Private Key DER:\n" + sm2PriDER1.toUpperCase()); | ||
} | ||
} |