Translating Elliptic Curve parameters (BC to MS)

試著忘記壹切 提交于 2019-11-28 13:09:09

When you are getting too many bytes (33 in this case) the first byte should be 0x00, and you need to remove it. When you are getting too few (technically speaking D=1 is valid) you need to insert zeros to fill the array out.

The reason is that .NET's structure expects D to look like it does to the underlying Windows CNG import API, which means that D is a fixed-with unsigned big endian big integer. BouncyCastle is giving you the BER INTEGER encoding, which requires inserting a 0x00 byte when the high bit of the most significant byte (bytes[0], big endian) is set in a number that should be considered positive.

BER also has a rule that the minimum number of bytes be used, which is why sometimes BouncyCastle gives a number that's too small.

Q.X and Q.Y are okay because the ECPoint encoding rules specify a fixed size big endian integer whose size is determined by the curve; which is why BouncyCastle has the GetEncoded method instead of just ToByteArrayUnsigned.

private static byte[] FixSize(byte[] input, int expectedSize)
{
    if (input.Length == expectedSize)
    {
        return input;
    }

    byte[] tmp;

    if (input.Length < expectedSize)
    {
        tmp = new byte[expectedSize];
        Buffer.BlockCopy(input, 0, tmp, expectedSize - input.Length, input.Length);
        return tmp;
    }

    if (input.Length > expectedSize + 1 || input[0] != 0)
    {
        throw new InvalidOperationException();
    }

    tmp = new byte[expectedSize];
    Buffer.BlockCopy(input, 1, tmp, 0, expectedSize);
    return tmp;
}

...

msEcp = new ECParameters();
msEcp.Curve = MsCurve;
msEcp.Q.X = bcPublKey.Q.XCoord.GetEncoded();
msEcp.Q.Y = bcPublKey.Q.YCoord.GetEncoded();
msEcp.D = FixSize(bcPrivKey.D.ToByteArrayUnsigned(), msEcp.Q.X.Length);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!