本文介绍了Flexiprovider - 如何使用格式化的密钥对加密/解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据此,使用flexiprovider以基于椭圆曲线的非对称算法加密/ de >。有一点修改,我要将公共和私钥转换为Base64为个人目的(如存储到数据库或文本文件)。我还在查看此,答案是请参阅此。但我的代码正在运行dekstop不在android设备,android和dekstop版本在java我认为是一个非常大的区别(只是为了清理我的问题信息)。好吧,在我的代码,当我要从生成的公钥创建格式化的公钥时,我得到一个错误(我认为同样的问题会发生,当我试图这样做的私钥)。
现在,这里是我的代码:

Im using flexiprovider to encrypt/de with asymmetric algorithm based on Elliptic Curve following this 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. But my code are running for dekstop not in android device, android and dekstop version in java i think is a really big difference (just for clean up my question information). Ok, in my code when im going to create the formatted public key from a generated public key i got an error (i think the same problem will happen when i try to do that for the private key).Now, here's my code:


  • Keypair生成器类。

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。

From that code above im going to store the string "privateKey" and "publicKey". Now im going to encrypt the message.


  • 发件人

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)

如何使用该命名的曲线生成公钥:1.3.36.3.3.2.8.1.1.1?

How can i generate that public key with that named curve: 1.3.36.3.3.2.8.1.1.1 ?


  • 收件人端(仅供参考)

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

If the sender has been succesfully encrypt the message, now im going to decrypt the message, here's my code (but not sure if this running without an error like the sender code above):

 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提供程序,我不能找到在 IESParameterSpec 在哪里使用AES128_CBC作为iesparameterspec,我该怎么做,如果想改变iesparam为AES128_CBC当我使用这个bouncy provider是什么意思?

Due to unsolved error with my code above because i think this flexiprovider aren't compatible with jdk-8 where the bug is in "KeyFactory kf = KeyFactory.getInstance("ECIES","FlexiEC")" line which can't find that named curve, i change and decide to use BouncyCastle provider for doing the EC encryption (ECIES) and it works. But there's a question again come in to my mind, as i can see in the Flexiprovider which is use ("AES128_CBC","HmacSHA1", null, null); as the IESParameterSpec.But for bouncycastle provider i can't find where is the IESParameterSpec which using AES128_CBC as the iesparameterspec, how can i do that if want to change the iesparam into AES128_CBC when i'm using this bouncy provider ?Somebody please explain about this iesparam spec in bouncy provider i'm new about this.

这是我的代码信息:


  • 密钥对生成器类

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




  • 加密类(发送方)

  • 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));
    ...
    




    • 解密类

    • 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));
      ...
      

      任何帮助都是合情合理的!

      Any help would be appriciate !

      这篇关于Flexiprovider - 如何使用格式化的密钥对加密/解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 17:42