2015-02-17 54 views
1

我無法弄清楚它應該是非常簡單的。ECDSA獲得C公鑰#

我有C#和BouncyCastle(也是C#)加密庫。

我只需要給一個字節數組作爲私鑰,指定使用的曲線並獲取公鑰。

我的曲線是SEC-P-256-K1/secp256k1,但真的如果你能幫助我導航選擇和課程的海洋,我不需要或關心我可以自己設定。

+0

也許這是不是你在找什麼,但有一個ECDSA庫Ruby和頭版自述文件有一個代碼示例顯示瞭如何執行此操作:https://github.com/DavidEGrayson/ruby_ecdsa您必須使用'private_key = ECDSA :: Format ::將私鑰從二進制字符串轉換爲整數。 IntegerOctetString.decode(str)' – 2015-02-18 18:13:03

+0

您是否嘗試在第二個paragrah中列出兩個加密庫?我只看到一個列出(BouncyCastle)。 – 2015-02-18 18:13:59

回答

1

馬丁的答案似乎很好,但它可以這樣做更容易:

public Tuple<byte[],byte[]> GetPublicKey(byte[] privateKey) 
{ 
    BigInteger privKeyInt = new BigInteger(+1, privateKey); 

    var parameters = SecNamedCurves.GetByName("secp256k1"); 
    ECPoint qa = parameters.G.Multiply(privKeyInt); 

    byte[] pubKeyX = qa.X.ToBigInteger().ToByteArrayUnsigned(); 
    byte[] pubKeyY = qa.Y.ToBigInteger().ToByteArrayUnsigned(); 

    return Tuple.Create(pubKeyX, pubKeyY); 
} 
1

這是解決方案。我被曲線構造函數弄糊塗了一個參數'q',它實際上應該是'p'(場的總模數)。

我也不明白爲什麼我必須這麼做我自己,比如點乘法得到公鑰。未讀EC數學的其他人如何知道這樣做?

爲什麼沒有「GetPubKey」方法!?!

噢,我希望這可以幫助別人。用戶友好不是BouncyCastle關於我猜的。

using Org.BouncyCastle.Security; 
using Org.BouncyCastle.Math.EC; 
using Org.BouncyCastle.Math; 
using Org.BouncyCastle.Crypto.Parameters; 
using System.Text.RegularExpressions; 

public static Tuple<byte[], byte[]> GetSecp256k1PublicKey(byte[] privateKey) 
     { 
      //Secp256k1 curve variables - https://en.bitcoin.it/wiki/Secp256k1 
      var privKeyInt = new BigInteger(+1, privateKey); 
      var a = new BigInteger("0"); 
      var b = new BigInteger("7"); 
      var GX = new BigInteger(+1, HexStringToByteArray("79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798")); 
      var GY = new BigInteger(+1, HexStringToByteArray("483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8")); 
      var n = new BigInteger(+1, HexStringToByteArray("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141")); 
      var h = new BigInteger("1"); 
      var p = new BigInteger(+1, HexStringToByteArray("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F")); 
      var q = h.Multiply(n).Mod(p); //Is this right??? 
      //- http://en.wikipedia.org/wiki/Elliptic_curve_cryptography 

      ECCurve curve = new Org.BouncyCastle.Math.EC.FpCurve(p, a, b); 
      ECPoint G = new Org.BouncyCastle.Math.EC.FpPoint(curve, new FpFieldElement(p, GX), new FpFieldElement(p, GY)); 

      var Qa = G.Multiply(privKeyInt); 

      byte[] PubKeyX = Qa.X.ToBigInteger().ToByteArrayUnsigned(); 
      byte[] PubKeyY = Qa.Y.ToBigInteger().ToByteArrayUnsigned(); 

      return Tuple.Create<byte[], byte[]>(PubKeyX, PubKeyY); 
     } 

     public static byte[] HexStringToByteArray(string hex) 
     { 
      if(String.IsNullOrWhiteSpace(hex)) 
       return new byte[0]; 

      hex = Regex.Replace(hex, "[\\s-\\{}]", ""); 

      if (hex.Length % 2 == 1) 
       throw new Exception("The binary key cannot have an odd number of digits."); 

      if (!Regex.IsMatch(hex, "(^|\\A)[0-9A-Fa-f]*(\\Z|$)")) 
       throw new Exception("Not hex."); 

      byte[] arr = new byte[hex.Length >> 1]; 

      hex = hex.ToUpper(); 

      for (int i = 0; i <hex.Length>> 1; ++i) 
      { 
       arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1]))); 
      } 

      return arr; 
     } 
+0

他們爲什麼會提供這樣的方法?公鑰是公開的,爲什麼在密鑰對生成後需要任何人重新生成它?此外,這是開源的;你有沒有考慮過貢獻? – 2015-02-21 01:24:27

+0

如果您有私鑰,但沒有公鑰。這可能發生在許多情況下。例如,當導入比特幣私鑰時,或者在我不信任盒外對生成器的情況下。 – 2015-02-24 22:49:39

+0

夠公平的。順便說一下,我認爲我在java api中看到了這樣一種方法 – 2015-02-24 23:28:26