4

当您有 P、Q、G、Y 和 X 时,.NET Framework (C#) 中是否有生成 40 个字符(公共?)指纹的现有方法,如下所示?

或者有人知道如何实现这一目标吗?

指纹:81F68001 29D928AD BEE41B78 AA862106 CAEAC892

编辑:这是我正在尝试做的一个例子:

    string P = "00F35DBCD6D4C296D2FE9118B659D02608B76FAC94BB58B10283F20390E2B259BAC602466162E9EF3E6A1590702CAE49B681A75A878E266F1AFAE0FA89DA5CA44A1551B517A3F80A9D6C630F9E7D239B437F7402DF8055069735894CD9D4708F8777B5E4F3E6A8B2D4EEE50DB2C96BA16D3C81FEB923697D649A8B7771B10E5B3F";
    string Q = "00B5AF039839043410E04C35BDDB30679969EBAC8B";
    string G = "00F300A68E54DE33A09001E28EC09F2ABF5DAF208774F2514D878D5587D870C91C6DE42B4705078C6F4438765050039C2950B6DE85AFC0D12A7A5C521782CB760918DF68F385A7F177DF50AA6BA0284090454106E422FCAE5390ADC00B859A433430019E970BFA614374DE1FB40C600345EF19DC01A122E4676C614DC29D3DC2FE";
    string Y = "00A5317849AF22BA6498F1EF973158C8BDA848BEB074CB141E629C927B18F29C8CE99815001BAAB2931F339B5C52A79BC3DCB0C5962C302707BA6FF1807EEB91D751BA723BB7512C20689AC5E67A1B656CDFD1BA2D4F6A44308509486AA8754B47784FC4C03E546897200388656BA5834A2CC0E18E58454FF60C1BA5411D6F50FD";

我错过了这个中间部分的代码。如何将 P、Q、G、Y 转换为指纹。我尝试了不同的方法,但未能成功生成我在尝试重新创建的应用程序中看到的指纹。

        /* convert public key (bigIntKey) into fingerprint */
        var bigIntHash = new BigInteger(SHA1.Create().ComputeHash(key.ToByteArray()));
        byte[] hash = bigIntHash.ToByteArray();

        if (hash.Length != 20)
        {
            throw new IndexOutOfRangeException();
        }

        for (int i = 0; i < 5; i++)
        {
            int lf = BitConverter.ToInt32(hash, i * 4);
            Debug.Write(lf.ToString("X") + " ");
        }

编辑2:

我试过这个,但这不起作用

        // switch P, Q, G, Y and separately to make it work.

        byte[] pArr = StringToByteArray(P);
        pArr = Tools.Endian.ReverseBytes(pArr);

        byte[] qArr = StringToByteArray(Q);
        qArr = Tools.Endian.ReverseBytes(qArr);

        byte[] gArr = StringToByteArray(G);
        gArr = Tools.Endian.ReverseBytes(gArr);

        byte[] yArr = StringToByteArray(Y);
        yArr = Tools.Endian.ReverseBytes(yArr);

        byte[] xArr = StringToByteArray(X);
        xArr = Tools.Endian.ReverseBytes(xArr);

        byte[] arr = Combine(pArr, qArr, gArr, yArr);

        DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();
        DSAParameters par = new DSAParameters();
        par.P = pArr;
        par.Q = qArr;
        par.G = gArr;
        par.Y = yArr;
        par.X = xArr;
        dsa.ImportParameters(par);
        var xml = dsa.ToXmlString(true);

它将在 ImportParameter 上失败。

谢谢

4

3 回答 3

2

MSDN 在此页面上提到了您需要做的工作。然后,从这个 SO page看看这个答案。接受的答案给出了以下代码(我引用):

var dsa = new DSACryptoServiceProvider();            
var privateKey = dsa.ExportParameters(true); // private key
var publicKey = dsa.ExportParameters(false); // public key

我认为您拥有一切所需的一切。

干杯!

于 2013-02-02T18:10:58.847 回答
2

您需要遵循 OTR 规范,其中说密钥的组件使用 MPI 编码,它指定为长度(32 位大端)后跟整数(大端,无前导零)

void Main()
{
    string P = "00F35DBCD6D4C296D2FE9118B659D02608B76FAC94BB58B10283F20390E2B259BAC602466162E9EF3E6A1590702CAE49B681A75A878E266F1AFAE0FA89DA5CA44A1551B517A3F80A9D6C630F9E7D239B437F7402DF8055069735894CD9D4708F8777B5E4F3E6A8B2D4EEE50DB2C96BA16D3C81FEB923697D649A8B7771B10E5B3F";
    string Q = "00B5AF039839043410E04C35BDDB30679969EBAC8B";
    string G = "00F300A68E54DE33A09001E28EC09F2ABF5DAF208774F2514D878D5587D870C91C6DE42B4705078C6F4438765050039C2950B6DE85AFC0D12A7A5C521782CB760918DF68F385A7F177DF50AA6BA0284090454106E422FCAE5390ADC00B859A433430019E970BFA614374DE1FB40C600345EF19DC01A122E4676C614DC29D3DC2FE";
    string Y = "00A5317849AF22BA6498F1EF973158C8BDA848BEB074CB141E629C927B18F29C8CE99815001BAAB2931F339B5C52A79BC3DCB0C5962C302707BA6FF1807EEB91D751BA723BB7512C20689AC5E67A1B656CDFD1BA2D4F6A44308509486AA8754B47784FC4C03E546897200388656BA5834A2CC0E18E58454FF60C1BA5411D6F50FD";

    var publicKey = 
                ToMPI(HexToBytes(P))
        .Concat(ToMPI(HexToBytes(Q)))
        .Concat(ToMPI(HexToBytes(G)))
        .Concat(ToMPI(HexToBytes(Y)))
        .ToArray();

    var fingerprint=BitConverter.ToString(SHA1.Create().ComputeHash(publicKey)).Replace("-","");
    fingerprint.Dump();
}

byte[] ToMPI(byte[] data)
{
    //Truncate leading 0 bytes
    data = data.SkipWhile(b=>b==0).ToArray();

    //Length prefix - 32 bit big-endian integer
    var lenBytes=new byte[4];
    lenBytes[0]=(byte)(data.Length>>24);
    lenBytes[1]=(byte)(data.Length>>16);
    lenBytes[2]=(byte)(data.Length>>8);
    lenBytes[3]=(byte)(data.Length>>0);

    return lenBytes.Concat(data).ToArray();
}

// from http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and-vice-versa
public static byte[] HexToBytes(String hex)
{
  int NumberChars = hex.Length;
  byte[] bytes = new byte[NumberChars / 2];
  for (int i = 0; i < NumberChars; i += 2)
    bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
  return bytes;
}
于 2013-02-03T11:30:54.600 回答
1

我已经使用这个类来生成 OTR DSA 密钥: https ://github.com/mohamedmansour/OTRLib/blob/master/Src/OTR/OTRUtilities/DSASigner.cs

使类公开并在没有构造函数参数的情况下调用。

var signer = new DSASigner();
var  _des_key_object = signer.GetDSAKeyParameters();

稍后重用相同的密钥:

string _dsa_key_1_p = _des_key_object.GetHexParamP();
string _dsa_key_1_q = _des_key_object.GetHexParamQ();
string _dsa_key_1_g = _des_key_object.GetHexParamG();
string _dsa_key_1_x = _des_key_object.GetHexParamX();

// 这可以是用于存储的 JSON。

var keysArray = new string[] { _dsa_key_1_p, _dsa_key_1_q, _dsa_key_1_g, _dsa_key_1_x };
_des_key_object = new DSAKeyParams(_des_key_objectJson[0], _des_key_objectJson[1], _des_key_objectJson[2], _des_key_objectJson[3]);
于 2018-04-07T16:10:28.420 回答