04 如何去掉sm2加密结果_C#实现SM2国密加密

本文档详细介绍了如何使用 C# 实现 SM2 密码算法进行加密操作,包括 `GeneralDigest` 类及其子类 `SM3Digest` 的关键代码实现,涉及数据更新、块处理和右移运算等核心步骤。通过阅读,读者可以理解 SM2 加密过程并将其应用于实际项目中。
摘要由CSDN通过智能技术生成

usingSystem;usingOrg.BouncyCastle.Utilities.Encoders;usingSystem.Text;usingOrg.BouncyCastle.Crypto;namespaceCom.Mlq.SM

{public abstract classGeneralDigest : IDigest

{private const int BYTE_LENGTH = 64;private byte[] xBuf;private intxBufOff;private longbyteCount;internalGeneralDigest()

{

xBuf= new byte[4];

}internalGeneralDigest(GeneralDigest t)

{

xBuf= new byte[t.xBuf.Length];

Array.Copy(t.xBuf,0, xBuf, 0, t.xBuf.Length);

xBufOff=t.xBufOff;

byteCount=t.byteCount;

}public void Update(byteinput)

{

xBuf[xBufOff++] =input;if (xBufOff ==xBuf.Length)

{

ProcessWord(xBuf,0);

xBufOff= 0;

}

byteCount++;

}public voidBlockUpdate(byte[] input,intinOff,intlength)

{//

//fill the current word// while ((xBufOff != 0) && (length > 0))

{

Update(input[inOff]);

inOff++;

length--;

}//

//process whole words.// while (length >xBuf.Length)

{

ProcessWord(input, inOff);

inOff+=xBuf.Length;

length-=xBuf.Length;

byteCount+=xBuf.Length;

}//

//load in the remainder.// while (length > 0)

{

Update(input[inOff]);

inOff++;

length--;

}

}public voidFinish()

{long bitLength = (byteCount << 3);//

//add the pad bytes.// Update(unchecked((byte)128));while (xBufOff != 0) Update(unchecked((byte)0));

ProcessLength(bitLength);

ProcessBlock();

}public virtual voidReset()

{

byteCount= 0;

xBufOff= 0;

Array.Clear(xBuf,0, xBuf.Length);

}public intGetByteLength()

{returnBYTE_LENGTH;

}internal abstract void ProcessWord(byte[] input, intinOff);internal abstract void ProcessLength(longbitLength);internal abstract voidProcessBlock();public abstract string AlgorithmName { get; }public abstract intGetDigestSize();public abstract int DoFinal(byte[] output, intoutOff);

}public classSupportClass

{///

///Performs an unsigned bitwise right shift with the specified number///

/// Number to operate on

/// Ammount of bits to shift

/// The resulting number from the shift operation

public static int URShift(int number, intbits)

{if (number >= 0)return number >>bits;else

return (number >> bits) + (2 << ~bits);

}///

///Performs an unsigned bitwise right shift with the specified number///

/// Number to operate on

/// Ammount of bits to shift

/// The resulting number from the shift operation

public static int URShift(int number, longbits)

{return URShift(number, (int)bits);

}///

///Performs an unsigned bitwise right shift with the specified number///

/// Number to operate on

/// Ammount of bits to shift

/// The resulting number from the shift operation

public static long URShift(long number, intbits)

{if (number >= 0)return number >>bits;else

return (number >> bits) + (2L << ~bits);

}///

///Performs an unsigned bitwise right shift with the specified number///

/// Number to operate on

/// Ammount of bits to shift

/// The resulting number from the shift operation

public static long URShift(long number, longbits)

{return URShift(number, (int)bits);

}

}public classSM3Digest : GeneralDigest

{public override stringAlgorithmName

{get{return "SM3";

}

}public override intGetDigestSize()

{returnDIGEST_LENGTH;

}private const int DIGEST_LENGTH = 32;private static readonly int[] v0 = new int[]{0x7380166f, 0x4914b2b9, 0x172442d7, unchecked((int) 0xda8a0600), unchecked((int) 0xa96f30bc), 0x163138aa, unchecked((int) 0xe38dee4d), unchecked((int) 0xb0fb0e4e)};private int[] v = new int[8];private int[] v_ = new int[8];private static readonly int[] X0 = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};private int[] X = new int[68];private intxOff;private int T_00_15 = 0x79cc4519;private int T_16_63 = 0x7a879d8a;publicSM3Digest()

{

Reset();

}public SM3Digest(SM3Digest t):base(t)

{

Array.Copy(t.X,0, X, 0, t.X.Length);

xOff=t.xOff;

Array.Copy(t.v,0, v, 0, t.v.Length);

}public override voidReset()

{base.Reset();

Array.Copy(v0,0, v, 0, v0.Length);

xOff= 0;

Array.Copy(X0,0, X, 0, X0.Length);

}internal override voidProcessBlock()

{inti;int[] ww =X;int[] ww_ = new int[64];for (i = 16; i < 68; i++)

{

ww[i]= P1(ww[i - 16] ^ ww[i - 9] ^ (ROTATE(ww[i - 3], 15))) ^ (ROTATE(ww[i - 13], 7)) ^ ww[i - 6];

}for (i = 0; i < 64; i++)

{

ww_[i]= ww[i] ^ ww[i + 4];

}int[] vv =v;int[] vv_ =v_;

Array.Copy(vv,0, vv_, 0, v0.Length);intSS1, SS2, TT1, TT2, aaa;for (i = 0; i < 16; i++)

{

aaa= ROTATE(vv_[0], 12);

SS1= aaa + vv_[4] +ROTATE(T_00_15, i);

SS1= ROTATE(SS1, 7);

SS2= SS1 ^aaa;

TT1= FF_00_15(vv_[0], vv_[1], vv_[2]) + vv_[3] + SS2 +ww_[i];

TT2= GG_00_15(vv_[4], vv_[5], vv_[6]) + vv_[7] + SS1 +ww[i];

vv_[3] = vv_[2];

vv_[2] = ROTATE(vv_[1], 9);

vv_[1] = vv_[0];

vv_[0] =TT1;

vv_[7] = vv_[6];

vv_[6] = ROTATE(vv_[5], 19);

vv_[5] = vv_[4];

vv_[4] =P0(TT2);

}for (i = 16; i < 64; i++)

{

aaa= ROTATE(vv_[0], 12);

SS1= aaa + vv_[4] +ROTATE(T_16_63, i);

SS1= ROTATE(SS1, 7);

SS2= SS1 ^aaa;

TT1= FF_16_63(vv_[0], vv_[1], vv_[2]) + vv_[3] + SS2 +ww_[i];

TT2= GG_16_63(vv_[4], vv_[5], vv_[6]) + vv_[7] + SS1 +ww[i];

vv_[3] = vv_[2];

vv_[2] = ROTATE(vv_[1], 9);

vv_[1] = vv_[0];

vv_[0] =TT1;

vv_[7] = vv_[6];

vv_[6] = ROTATE(vv_[5], 19);

vv_[5] = vv_[4];

vv_[4] =P0(TT2);

}for (i = 0; i < 8; i++)

{

vv[i]^=vv_[i];

}//Reset

xOff = 0;

Array.Copy(X0,0, X, 0, X0.Length);

}internal override void ProcessWord(byte[] in_Renamed, intinOff)

{int n = in_Renamed[inOff] << 24;

n|= (in_Renamed[++inOff] & 0xff) << 16;

n|= (in_Renamed[++inOff] & 0xff) << 8;

n|= (in_Renamed[++inOff] & 0xff);

X[xOff]=n;if (++xOff == 16)

{

ProcessBlock();

}

}internal override void ProcessLength(longbitLength)

{if (xOff > 14)

{

ProcessBlock();

}

X[14] = (int) (SupportClass.URShift(bitLength, 32));

X[15] = (int) (bitLength & unchecked((int) 0xffffffff));

}public static void IntToBigEndian(int n, byte[] bs, intoff)

{

bs[off]= (byte) (SupportClass.URShift(n, 24));

bs[++off] = (byte) (SupportClass.URShift(n, 16));

bs[++off] = (byte) (SupportClass.URShift(n, 8));

bs[++off] = (byte) (n);

}public override int DoFinal(byte[] out_Renamed, intoutOff)

{

Finish();for (int i = 0; i < 8; i++)

{

IntToBigEndian(v[i], out_Renamed, outOff+ i * 4);

}

Reset();returnDIGEST_LENGTH;

}private int ROTATE(int x, intn)

{return (x << n) | (SupportClass.URShift(x, (32 -n)));

}private int P0(intX)

{return ((X) ^ ROTATE((X), 9) ^ ROTATE((X), 17));

}private int P1(intX)

{return ((X) ^ ROTATE((X), 15) ^ ROTATE((X), 23));

}private int FF_00_15(int X, int Y, intZ)

{return (X ^ Y ^Z);

}private int FF_16_63(int X, int Y, intZ)

{return ((X & Y) | (X & Z) | (Y &Z));

}private int GG_00_15(int X, int Y, intZ)

{return (X ^ Y ^Z);

}private int GG_16_63(int X, int Y, intZ)

{return ((X & Y) | (~ X &Z));

}//[STAThread]//public static void Main()//{//byte[] md = new byte[32];//byte[] msg1 = Encoding.Default.GetBytes("ererfeiisgod");//SM3Digest sm3 = new SM3Digest();//sm3.BlockUpdate(msg1, 0, msg1.Length);//sm3.DoFinal(md, 0);//System.String s = new UTF8Encoding().GetString(Hex.Encode(md));//System.Console.Out.WriteLine(s.ToUpper());//Console.ReadLine();//}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值