bcgit / pc-dart

Pointy Castle - Dart Derived Bouncy Castle APIs
MIT License
237 stars 122 forks source link

Encode ECDSA KeyPair to PEM #30

Closed kwado-tech closed 4 years ago

kwado-tech commented 4 years ago

I am urgently in need of a documentation on how to encode ECDSA keypair to pem using pointy castle but with no success.

Am new to encryption and was able to generate ECDSA keypairs but stuck with encoding and decoding to and from PEM since i'll have to persist both keys as strings

Please point me to the right resource to look through @stevenroose

Any contributions are welcome

Thanks for your assistance

AKushWarrior commented 4 years ago

Steven is no longer a maintainer on this project (he, presumably, is consumed with some other work). If you need further assistance, you should probably tag @mwcw, who is on the BouncyCastle team and is the lead maintainer of this project. You can also tag me; I'm not on the BouncyCastle team, but I am an active contributor to this library.

As of right now, it is not possible to encode/decode asymmetric keys. Browsing around, you can find encoding for RSA (check out https://pub.dev/packages/rsa_encrypt) but I could not find a PEM encoder for ECDSA.

If you would like to code such an encoder, you can always submit a PR.

kwado-tech commented 4 years ago

Thanks for your response @AKushWarrior I appreciate it. Same here couldn't find anything on encoding ECDSA to PEM. Notes on RSA encoding to PEM describes using asn1lib with passed-in parameters from generated key and base64 encode the encodedBytes.

My challenge currently is knowing how to do this with ECDSA. Can you be of assistance please @mwcw

Any assistance is appreciated.

Ephenodrom commented 4 years ago

@chrisoftech Please checkout my dart package called "Basic Utils".

https://github.com/Ephenodrom/Dart-Basic-Utils

I added some functionality for elliptic curve key pairs to the X509Utils class.

AsymmetricKeyPair generateEcKeyPair();
String encodeEcPublicKeyToPem(ECPublicKey publicKey); 
String encodeEcPrivateKeyToPem(ECPrivateKey ecPrivateKey); 
String generateEccCsrPem(Map<String, String> attributes, ECPrivateKey privateKey, ECPublicKey publicKey);

The functionality is based on the pointy castle package. I think this should cover your request.

This work was done from scratch due to i could not find any example on the internet. Therefore i had to study the corresponding RFCs to find out how to construct the ASN1 structure for the public and private key pem.

kwado-tech commented 4 years ago

Will take a look @Ephenodrom thanks a lot

Ephenodrom commented 4 years ago

@chrisoftech does this help? Can we close this issue?

kwado-tech commented 4 years ago

Yes definitely. Closing myself @Ephenodrom

ranbeuer commented 4 years ago

@chrisoftech Please checkout my dart package called "Basic Utils".

https://github.com/Ephenodrom/Dart-Basic-Utils

I added some functionality for elliptic curve key pairs to the X509Utils class.

AsymmetricKeyPair generateEcKeyPair();
String encodeEcPublicKeyToPem(ECPublicKey publicKey); 
String encodeEcPrivateKeyToPem(ECPrivateKey ecPrivateKey); 
String generateEccCsrPem(Map<String, String> attributes, ECPrivateKey privateKey, ECPublicKey publicKey);

The functionality is based on the pointy castle package. I think this should cover your request.

This work was done from scratch due to i could not find any example on the internet. Therefore i had to study the corresponding RFCs to find out how to construct the ASN1 structure for the public and private key pem.

I tried this for a project I'm working on, but when I try to verify the CSR, I get that it's not valid. Also, i believe that the UID field is not supported by your library, it would be awesome if you could support it in future releases.

Ephenodrom commented 4 years ago

@ranbeuer where did you try to verify the CSR?

ranbeuer commented 4 years ago

@Ephenodrom https://certlogik.com/decoder/ I'm comparing against one I got from a working android app I have. Some bits are off, apparently.

ranbeuer commented 4 years ago

@Ephenodrom I'm trying to replicate something like this: ` public String createPKI(String mdnString) { //phone number try {

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
        //KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "SC");

        ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1");
        keyPairGenerator.initialize(ecGenSpec, new SecureRandom());

        KeyPair kp =  keyPairGenerator.generateKeyPair();

        publicKey = kp.getPublic();
        privateKey = kp.getPrivate();

        PKCS10CertificationRequest kpGen = new PKCS10CertificationRequest("SHA256withECDSA", new X509Name(String.format("UID=%s", mdnString)), publicKey, null, privateKey);

        String certRequest = Base64.encodeToString(kpGen.getEncoded(), Base64.DEFAULT);
        certRequest = certRequest.replace("\n", "");

        return certRequest;

    } catch(Exception e) {
        if (Constants.DEBUG) {
            Log.v("Exception", e.getMessage());
        }
        return null;
    }
}

` I already managed to create a similar CSR, but when I try to verify it against one from my app, I get that it's not correctly formed.

Ephenodrom commented 3 years ago

@ranbeuer Hello I finally had some time to check this. Yes there is a problem with setting the unused bits in the BitString class while encoding it. Will try to fix this.