Is there a existing method within .NET Framework (C#) to generate a 40 char (public?) fingerprint as shown below, when you have P, Q, G, Y and X?
Or would anybody know on how to achieve this?
Fingerprint: 81F68001 29D928AD BEE41B78 AA862106 CAEAC892
EDIT: here is an example of what i'm trying to do:
string P = "00F35DBCD6D4C296D2FE9118B659D02608B76FAC94BB58B10283F20390E2B259BAC602466162E9EF3E6A1590702CAE49B681A75A878E266F1AFAE0FA89DA5CA44A1551B517A3F80A9D6C630F9E7D239B437F7402DF8055069735894CD9D4708F8777B5E4F3E6A8B2D4EEE50DB2C96BA16D3C81FEB923697D649A8B7771B10E5B3F";
string Q = "00B5AF039839043410E04C35BDDB30679969EBAC8B";
string G = "00F300A68E54DE33A09001E28EC09F2ABF5DAF208774F2514D878D5587D870C91C6DE42B4705078C6F4438765050039C2950B6DE85AFC0D12A7A5C521782CB760918DF68F385A7F177DF50AA6BA0284090454106E422FCAE5390ADC00B859A433430019E970BFA614374DE1FB40C600345EF19DC01A122E4676C614DC29D3DC2FE";
string Y = "00A5317849AF22BA6498F1EF973158C8BDA848BEB074CB141E629C927B18F29C8CE99815001BAAB2931F339B5C52A79BC3DCB0C5962C302707BA6FF1807EEB91D751BA723BB7512C20689AC5E67A1B656CDFD1BA2D4F6A44308509486AA8754B47784FC4C03E546897200388656BA5834A2CC0E18E58454FF60C1BA5411D6F50FD";
i'm missing the code for this intermediate piece. how do i convert P, Q, G, Y into the fingerprint. I tried different approaches, but i'm unsuccessful generating the fingerprint i see in the application that i'm trying to recreate.
/* 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") + " ");
}
EDIT2:
i tried this, but that is not working
// 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);
It will fail on the ImportParameter.
Thank you
You need to follow the OTR spec, which says the components of the key use MPI encoding, which it specifies as the length (32 bit big-endian) followed by the integer (big-endian, no leading zeros)
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;
}