Flexiprovider - 如何 encrypt/de 使用格式化的密钥对

Flexiprovider - How to encrypt/de with formatted keypair

我正在使用 flexiprovider encrypt/de 以及基于此 tutorial. With a little modification, i'm gonna convert the public and the private key into Base64 for personal purpose (like storing into the database or text file). I'm also looking at this question and the answer is refer to this thread 之后的椭圆曲线的非对称算法。但是我的代码是 运行 for dekstop not in android device, android and dekstop version in java 我认为这是一个非常大的区别(只是为了清理我的问题信息) .好的,在我的代码中,当我要从生成的 public 密钥创建格式化的 public 密钥时,我遇到了一个错误(我认为当我尝试为私钥执行此操作时会发生同样的问题) . 现在,这是我的代码:

import org.jivesoftware.smack.util.Base64; //or whatever to convert into Base64
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.KeyFactory;
import javax.crypto.Cipher;   
import de.flexiprovider.common.ies.IESParameterSpec;
import de.flexiprovider.core.FlexiCoreProvider;
import de.flexiprovider.ec.FlexiECProvider;
import de.flexiprovider.ec.parameters.CurveParams;
import de.flexiprovider.ec.parameters.CurveRegistry.BrainpoolP160r1;
import de.flexiprovider.pki.PKCS8EncodedKeySpec;
import de.flexiprovider.pki.X509EncodedKeySpec;
...
  Security.addProvider(new FlexiCoreProvider());
  Security.addProvider(new FlexiECProvider());

  KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECIES","FlexiEC");

  CurveParams ecParams = new BrainpoolP160r1();

  kpg.initialize(ecParams, new SecureRandom());
  KeyPair keyPair = kpg.generateKeyPair();

  PublicKey pubKey = keyPair.getPublic();
  byte[] encod_pubK = pubKey.getEncoded();

  String publicKey = Base64.encodeBytes(encod_pubK);
  System.out.println("Public Key :" +publikKey);

  PrivateKey privKey = keyPair.getPrivate();
  byte[] encod_privK = privKey.getEncoded();
  String privateKey = Base64.encodeBytes(encod_privK);
  System.out.println("Private Key :" +privateKey);

根据上面的代码,我将存储字符串 "privateKey" 和 "publicKey"。现在我要加密消息了。

import (same as code above)
...
  Security.addProvider(new FlexiCoreProvider());
  Security.addProvider(new FlexiECProvider());
  Cipher cipher = Cipher.getInstance("ECIES","FlexiEC");
  IESParameterSpec iesParams = new IESParameterSpec ("AES128_CBC","HmacSHA1", null, null);

  byte[] decodedPubKey = Base64.decode(publicKey);

  X509EncodedKeySpec formatted_public = new X509EncodedKeySpec(decodedPubKey);
  KeyFactory kf = KeyFactory.getInstance("ECIES","FlexiEC");

  PublicKey publicKey = kf.generatePublic(formatted_public); // <--- I got error when hit this row

  cipher.init(Cipher.ENCRYPT_MODE, publicKey, iesParams);

  byte[] block = "this my message".getBytes();
  System.out.println("Plaintext: "+ new String(block));

  byte [] Ciphered = cipher.doFinal(block);
  System.out.println("Ciphertext : "+ Base64.encodeBytes(Ciphered));

上述发件人代码的错误是:

Exception in thread "main" de.flexiprovider.api.exceptions.InvalidKeySpecException:     java.lang.RuntimeException: java.security.InvalidAlgorithmParameterException: Caught IOException("Unknown named curve: 1.3.36.3.3.2.8.1.1.1")
at de.flexiprovider.ec.keys.ECKeyFactory.generatePublic(ECKeyFactory.java:205)
at de.flexiprovider.api.keys.KeyFactory.engineGeneratePublic(KeyFactory.java:39)
at java.security.KeyFactory.generatePublic(KeyFactory.java:328)

我如何生成 public 带有命名曲线的密钥:1.3.36.3.3.2.8.1.1.1?

如果发件人已成功加密邮件,现在我要解密邮件,这是我的代码(但不确定这个 运行 是否像上面的发件人代码一样没有错误):

 byte[] decodedPrivateKey = Base64.decode(privateKey);
 PKCS8EncodedKeySpec formatted_private = new PKCS8EncodedKeySpec(decodedPrivateKey);

 cipher.init(Cipher.DECRYPT_MODE, privKey, iesParams);
 byte[] decryptedCipher = cipher.doFinal(Ciphered);
 System.out.println("Decrypted message : "+ new String (decryptedCipher));

由于我上面的代码有未解决的错误,因为我认为这个 flexiprovider 与 jdk-8 不兼容,错误在 "KeyFactory kf = KeyFactory.getInstance("ECIES","FlexiEC")"找不到该命名曲线的行,我更改并决定使用 BouncyCastle 提供程序进行 EC 加密 (ECIES) 并且它有效。但是我又想到了一个问题,正如我在 Flexiprovider 中看到的那样,它使用 ("AES128_CBC","HmacSHA1", null, null); 作为IESParameterSpec。 但是对于 bouncycastle 提供者,我找不到使用 AES128_CBC 作为 iesparameterspec 的 IESParameterSpec 在哪里,如果想将 iesparam 更改为 [=41= 我该怎么做] 当我使用这个有弹性的供应商时? 有人请在弹性提供程序中解释这个 iesparam 规范我是新手。

这是我的信息代码:

  • 密钥对生成器Class
import codec.Base64; // or whatever which can use to base64 encoding
import static java.lang.System.out;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

...

   Security.addProvider(new BouncyCastleProvider());

   KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECIES", "BC");
   ECGenParameterSpec brainpoolP160R1 = new ECGenParameterSpec("brainpoolP160R1");

   // I'm Still using this 160 bit GF(*p*) to keep the algorithm running fast rather than 256 or above 
   kpg.initialize(brainpoolP160R1);

   KeyPair kp = kpg.generateKeyPair();

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

   byte[] PublicKey = publicKey.getEncoded();
   byte[] PrivateKey = privateKey.getEncoded();

   out.println("Encoded Public : "+Base64.encode(PublicKey));
   out.println("\nEncoded Private : "+Base64.encode(PrivateKey));
...
  • 加密class(发送端)
import codec.Base64;
import codec.CorruptedCodeException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
...
    Security.addProvider(new BouncyCastleProvider());

// Assume that we know the encoded public key then return it by decode the public key
    byte[] decodedPublic = Base64.decode("MEIwFAYHKoZIzj0CAQYJKyQDAwIIAQEBAyoABNXclcmtUt8/rlGN47pc8ZpxkWgNgtKeeHdsVD0kIWLUMEULnchGZPA=".getBytes());

    X509EncodedKeySpec formatted_public = new X509EncodedKeySpec(decodedPublic);
    KeyFactory kf = KeyFactory.getInstance("EC","BC");
    PublicKey pubKey = kf.generatePublic(formatted_public);

    Cipher c = Cipher.getInstance("ECIES", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey); // How can i put the AES128_CBC for ies parameter ? is that possible

    byte[] cipher = c.doFinal("This is the message".getBytes());
    System.out.println("Ciphertext : "+ Base64.encode(cipher));
...
  • 解密class(接收方)
import codec.Base64;
import codec.CorruptedCodeException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
...
    Security.addProvider(new BouncyCastleProvider());
// Assume that we know the encoded private key
    byte[] decodedPrivate = Base64.decode("MHECAQAwFAYHKoZIzj0CAQYJKyQDAwIIAQEBBFYwVAIBAQQUQmA9ifs472gNHBc5NSGYq56TlOKgCwYJKyQDAwIIAQEBoSwDKgAE1dyVya1S3z+uUY3julzxmnGRaA2C0p54d2xUPSQhYtQwRQudyEZk8A==".getBytes());

    PKCS8EncodedKeySpec formatted_private = new PKCS8EncodedKeySpec(decodedPrivate);
    KeyFactory kf = KeyFactory.getInstance("EC", "BC");
    PrivateKey privKey = kf.generatePrivate(formatted_private);

    Cipher c = Cipher.getInstance("ECIES");
    c.init(Cipher.DECRYPT_MODE, privKey); //How can i adding the **AES128_CBC** ies param ?

// Assume that we know the encoded cipher text
    byte[] plaintext = c.doFinal(Base64.decode("BKbCsKY7gDPld+F4jauQXvKSayYCt6vOjIGbsyXo5fHWo4Ax+Nt5BQ5FlkAGksFNRQ46agzfxjfuoxWkVfnt4gReDmpPYueUbiRiHp1Gwp0="));
    System.out.println("\nPlaintext : "+ new String (plaintext));
...

如有帮助将不胜感激!