鸿蒙仓颉语言【cryptocj 库】RC2、 RC4 、AES对称加密算法

2 提供RC2、 RC4 、AES对称加密算法

前置条件:NA

场景:

  1. 支持对称加密算法。

约束:RC2密钥长度一般16字节,加密块长度8字节;AES加密块长度16字节

性能: 支持版本几何性能持平

可靠性: NA

2.1 RC2

RC2 是一种对称加密算法,所见到的安全解决方案中,使用 RC2 的算法不多,从资料上看,RC2 算法可以替代 DES 算法,而且计算速度快,能在 16 位计算机上实现,密钥长度从 1 到 128 字节都可以。一般采用 16 字节,计算的数据块为 8 字节。

支持 ecb、cbc、cfb64、ofb64 加解密

2.1.1 主要接口

注意:

  • RC2 一般采用 16 字节,计算的数据块为 8 字节,不足位补 \0,输出缓存区为一个块长 8 字节
  • 偏移量每次加解密操作需要重新赋值
  • 密钥长度从 1 到 128 字节都可以,一般采用 16 字节。
  • 加解密必须设置密钥
// 加密标识 1
public let RC2_ENCRYPT: Int32 = 1
// 解密标识 0
public let RC2_DECRYPT: Int32 = 0
// 加密块长
public let RC2_BLOCK: Int32 = 8
// 密钥长度
public let RC2_KEY_LENGTH: Int32 = 16
class RC2KEY

RC2KEY 类

public class RC2KEY {
    /*
     * 初始化 RC2KEY
     */
    public init()
}
2.1.2 全局函数
/*
 * 设置密钥
 * 
 * 参数 key - RC2 的密钥类
 * 参数 data - 密钥数据,不能为空
 * 参数 bits - 密钥数据的位数
 * 返回值 Unit
 */
public func rc2SetKey(key: RC2KEY, data: Array<UInt8>, bits: Int32): Unit 

/*
 * RC2 ecb 加解密计算
 * 
 * 参数 inside - 输入数据,一个块的长度 8
 * 参数 out - 输出缓存区,一个块的长度 8
 * 参数 key - RC2 的密钥类
 * 参数 enc - 加密/解密模式, 加密:RC2_ENCRYPT, 解密:RC2_DECRYPT
 * 返回值 Unit
 */
public func rc2EcbEncrypt(inside: Array<UInt8>, out: Array<UInt8>, key: RC2KEY, enc: Int32): Unit

/*
 * RC2 cbc加密/解密计算;
 * 
 * 参数 inside - 输入数据,一个块的长度 8
 * 参数 out - 输出缓存区,一个块的长度 8
 * 参数 ks - RC2 的密钥类
 * 参数 iv - 初始化向量
 * 参数 enc - 加密/解密模式, 加密:RC2_ENCRYPT, 解密:RC2_DECRYPT
 * 返回值 Unit
 */
public func rc2CbcEncrypt(inside: Array<UInt8>, out: Array<UInt8>, ks: RC2KEY, iv: Array<UInt8>, enc: Int32): Unit

/*
 * RC2的cfb64 加密/解密计算
 * 
 * 参数 inside - 输入数据,一个块的长度 8
 * 参数 out - 输出缓存区,一个块的长度 8
 * 参数 schedule - RC2 的密钥类
 * 参数 ivec - 初始化向量
 * 参数 num - ivec 索引
 * 参数 enc - 加密/解密模式, 加密:RC2_ENCRYPT, 解密:RC2_DECRYPT
 * 返回值 Unit
 */
public func rc2Cfb64Encrypt(inside: Array<UInt8>, out: Array<UInt8>, schedule: RC2KEY, ivec: Array<UInt8>, num: Int32, enc: Int32): Unit

/*
 * RC2的ofb64 加密
 * 
 * 参数 inside - 输入数据,一个块的长度 8
 * 参数 out - 输出缓存区,一个块的长度 8
 * 参数 schedule - RC2 的密钥类
 * 参数 ivec - 初始化向量
 * 参数 num - ivec 索引( 0<= num < RC2_BLOCK)
 * 返回值 Unit
 */
public func rc2Ofb64Encrypt(inside: Array<UInt8>, out: Array<UInt8>, schedule: RC2KEY, ivec: Array<UInt8>, num: Int32): Unit
2.1.3 示例
from crypto4cj import rc2cj.*
from crypto4cj import utils.*
from encoding import base64.*
from encoding import hex.*
from std import collection.*
from std import math.*

main() {    
    var rc2key = RC2KEY()
    var keys: String = "1234567896465451"
    var datas: String = "helloword"
    var res: Array<UInt8> = Array<UInt8>(8, item: 0)
    rc2SetKey(rc2key, keys.toUtf8Array(), 0)

    // 编码
    var inside: Array<UInt8> = datas.toUtf8Array()
    var insides2: ArrayList<Array<UInt8>> = arrayTo2Array(inside, 8)
    var a: ArrayList<UInt8> = ArrayList<UInt8>()
    for(i in 0..insides2.size) { 
        rc2EcbEncrypt(insides2[i], res, rc2key, RC2_ENCRYPT)
        var b = res
        a.appendAll(b)
    }
    var resultE = toHexString(a.toArray())
    if(resultE != "97d61c569253660da654fb13588f9c84") {
        return -1
    }

    // 解码
    var deRes: Array<UInt8> = Array<UInt8>(8, item: 0)
    var deData = fromHexString(resultE).getOrThrow()
    var insides3: ArrayList<Array<UInt8>> = arrayTo2Array(deData, 8)
    var c: ArrayList<UInt8> = ArrayList<UInt8>() 
    for(i in 0..insides3.size) { 
        rc2EcbEncrypt(insides3[i], deRes, rc2key, RC2_DECRYPT)
        var b = deRes
        c.appendAll(b)
    }

    var decryptRes = String.fromUtf8(c.toArray())
    if(!decryptRes.contains(datas)) {
        return -1
    }
    return 0
}

运行结果如下:

0

2.2 RC4

RC4(Ron Rivest Cipher 4)是一种流加密算法,密钥长度可变。它加解密使用相同的密钥,属于对称加密算法,是使用最广泛的序列密码。RC4 是一种基于非线性数据表变换的序列密码。它以一个足够大的数据表(S盒)为基础,对表进行非线性变换,产生非线性的密钥流序列。它是一个可变密钥长度、面向字节操作的序列密码,该算法以随机置换作为基础。

支持 rc4 加解密

2.2.1 主要接口
class RC4KEY

RC4KEY 类

public class RC4KEY {
    /*
     * 初始化 RC4KEY
     */
    public init()
2.2.2 全局函数
/*
 * 设置密钥
 * 
 * 参数 key - RC4 的密钥类
 * 参数 data - 密钥数据
 * 返回值 Unit
 */
public func rc4SetKey(key: RC4KEY, data: Array<UInt8>): Unit 

/*
 * RC4 加解密计算
 * 
 * 参数 key - key 值
 * 参数 indata - 加密的数据
 * 参数 outdata - 加解密后的数据
 * 返回值 Unit
 */
public func rc4(key: RC4KEY, indata: Array<UInt8>, outdata: Array<UInt8>): Unit
2.1.3 示例
from crypto4cj import rc4cj.*
from encoding import base64.*
from std import collection.*
from std import math.*

main() {    
    var keys: Array<UInt8> = "1234567891111111".toUtf8Array()
    var indata: Array<UInt8> = "helloword".toUtf8Array()
    var encodeRes = rc4Encode(indata, keys)
    var decodeRes = rc4Decode(encodeRes, keys)
    if(toBase64String(encodeRes) != "Dqd7cGrLT0a7" || String.fromUtf8(decodeRes) != "helloword") {
        return -1
    }
    return 0
}

func rc4Encode(indata: Array<UInt8>, keys: Array<UInt8>): Array<UInt8> {
    var indataLen: Int32 = Int32(indata.size)
    var keysLen: Int32 = Int32(keys.size)
    var outdata: Array<UInt8> = Array<UInt8>(Int64(indataLen) , item: 0)

    if(indataLen == 0 || keysLen == 0) {
        return outdata
    }

    var key = RC4KEY()
    rc4SetKey(key, keys)
    rc4(key, indata, outdata)
    return outdata
}

func rc4Decode(indata: Array<UInt8>, keys: Array<UInt8>): Array<UInt8> {
    var indataLen: Int32 = Int32(indata.size)
    var keysLen: Int32 = Int32(keys.size)
    var outdata: Array<UInt8> = Array<UInt8>(Int64(indataLen) , item: 0)

    if(indataLen == 0 || keysLen == 0) {
        return outdata
    }

    var key = RC4KEY()
    rc4SetKey(key, keys)
    rc4(key, indata, outdata)
    return outdata
}

运行结果如下:

0

2.3 AES

密码学中的高级加密标准(Advanced Encryption Standard,AES),又称 Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

支持 aes、ecb、cbc、cfb128、cfb1、cfb8、ofb128、Ige、bilge、wrap、unwrap 加解密

注意:

  • AES 计算的数据块一般为 16 字节(或16字节的倍数),不足位补\0
  • 调用加密函数之前,必须先设置加密key:aesSetEncryptKey
  • 调用解密函数之前,必须先设置解密key:aesSetDecryptKey
  • 对于 aesCbcEncrypt 加密解密,每次调用前必须先初始化 ivec 向量, ivec 一般为 16 字节
  • 密码长度支持 128/192/256 bits
2.3.1 主要接口
// 加密标识 1 
public let AES_ENCRYPT: Int32 = 1
// 解密标识 0
public let AES_DECRYPT: Int32 = 0
// 加密块长
public let AES_BLOCK_SIZE: Int32 = 16
class AESKEY
/*
 * 初始化 AESKEY 
 */
public init()
2.3.2 全局函数

注意:

  • userKey 长度 16、24、32
  • bits 长度 对应为 128、192、256
  • 加解密密钥需相同
func aesSetEncryptKey
/*
 * 设置加密密钥
 * 
 * 参数 userKey - 密钥,必须为 16、24、32
 * 参数 bits - 密钥位数,与 userKey ,对应为 128、192、256
 * 参数 key - AESKEY
 * 返回值 Unit
 */
public func aesSetEncryptKey(userKey: Array<UInt8>, bits: Int32, key: AESKEY): Unit
func aesSetDecryptKey
/*
 * 设置解密密钥(加解密的参数需一致)
 * 
 * 参数 userKey - 密钥,必须为 16、24、32
 * 参数 bits - 密钥位数,与 userKey ,对应为 128、192、256
 * 参数 key - AESKEY
 * 返回值 Unit
 */
public func aesSetDecryptKey(userKey: Array<UInt8>, bits: Int32, key: AESKEY): Unit
func aesEncrypt

注意:

  • AES 计算的数据块一般为 16 字节(或16字节的倍数),不足位补\0, 输出缓存区为一个数据块长 16 字节
/*
 * 加密数据
 * 
 * 参数 inside - 加密数据,一个数据块长 16 字节
 * 参数 outside - 输出缓存区,一个数据块长 16 字节
 * 参数 key - AESKEY
 * 返回值 Unit 
 */
public func aesEncrypt(inside: Array<UInt8>, outside: Array<UInt8>, key: AESKEY): Unit
func aesDecrypt

注意:

  • AES 计算的数据块一般为 16 字节(或16字节的倍数),不足位补\0,输出缓存区为一个数据块长 16 字节
/*
 * 解密数据
 * 
 * 参数 inside - 解密数据,一个数据块长 16 字节
 * 参数 outside - 输出缓存区,一个数据块长 16 字节
 * 参数 key - AESKEY
 * 返回值 Unit 
 */
public func aesDecrypt(inside: Array<UInt8>, outside: Array<UInt8>, key: AESKEY): Unit
func aesEcbEncrypt

注意:

  • AES 计算的数据块一般为 16 字节(或16字节的倍数),不足位补\0,输出缓存区为一个数据块长 16 字节
/*
 * 加解密数据
 * 
 * 参数 inside - 输入数据,一个数据块长 16 字节
 * 参数 outside - 输出缓存区,一个数据块长 16 字节
 * 参数 key - AESKEY
 * 参数 enc - 加解密参数,加密: AES_ENCRYPT = 1,解密:AES_DECRYPT = 0
 * 返回值 Unit 
 */
public func aesEcbEncrypt(inside: Array<UInt8>, outside: Array<UInt8>, key: AESKEY, enc: Int32): Unit
func aesCbcEncrypt

注意:

  • AES 计算的数据块一般为 16 字节(或16字节的倍数),不足位补\0,输出缓存区为一个数据块长 16 字节
  • 对于加密解密,每次调用前必须先初始化 ivec 向量, ivec 必须是 16 字节
/*
 * 加解密数据
 * 
 * 参数 inside - 输入数据,一个数据块长 16 字节
 * 参数 outside - 输出缓存区,一个数据块长 16 字节
 * 参数 key - AESKEY
 * 参数 ivec - 初始向量
 * 参数 enc - 加解密参数,加密: AES_ENCRYPT = 1,解密:AES_DECRYPT = 0
 * 返回值 Unit 
 */
public func aesCbcEncrypt(inside: Array<UInt8>, outside: Array<UInt8>, key: AESKEY, ivec: Array<UInt8>, enc: Int32): Unit
func aesCfb128Encrypt

注意:

  • CFB128 模式加密和解密均使用 aesSetEncryptKey,这一点比较反常,务必记住。
  • CFB128 模式可一次性加解密。
  • 对于加密解密,每次调用前必须先初始化 ivec 向量, ivec 必须是 16 字节
  • CFB128 单词中的 128 属于 cfb 模式中加解密时分组继续分段的段的大小,与密钥 128 无关
/*
 * 加解密数据
 * 
 * 参数 inside - 输入数据,长度任意
 * 参数 outside - 输出数据,长度与输入数据相等
 * 参数 key - AESKEY
 * 参数 ivec - 可读写的一块内存。长度必须是16字节。
 * 参数 enc - 加解密参数,加密: AES_ENCRYPT = 1,解密:AES_DECRYPT = 0
 * 返回值 Unit 
 */
public func aesCfb128Encrypt(inside: Array<UInt8>, outside: Array<UInt8>, key: AESKEY, ivec: Array<UInt8>, enc: Int32): Unit
func aesCfb1Encrypt

注意:

  • CFB1 模式加密和解密均使用 aesSetEncryptKey,这一点比较反常,务必记住。
  • CFB1 模式可一次性加解密。
  • 对于加密解密,每次调用前必须先初始化 ivec 向量, ivec 必须是 16 字节
  • CFB1 单词中的 1 属于 cfb 模式中加解密时分组继续分段的段的大小,与密钥 128 无关
/*
 * 加解密数据
 * 
 * 参数 inside - 输入数据,长度任意
 * 参数 outside - 输出数据,长度与输入数据相等
 * 参数 key - AESKEY
 * 参数 ivec - 可读写的一块内存。长度必须是16字节。
 * 参数 enc - 加解密参数,加密: AES_ENCRYPT = 1,解密:AES_DECRYPT = 0
 * 返回值 Unit 
 */
public func aesCfb1Encrypt(inside: Array<UInt8>, outside: Array<UInt8>, key: AESKEY, ivec: Array<UInt8>, enc: Int32): Unit
func aesCfb8Encrypt

注意:

  • CFB8 模式加密和解密均使用 aesSetEncryptKey,这一点比较反常,务必记住。
  • CFB8 模式可一次性加解密。
  • 对于加密解密,每次调用前必须先初始化 ivec 向量, ivec 必须是 16 字节
  • CFB8 单词中的 8 属于 cfb 模式中加解密时分组继续分段的段的大小,与密钥 128 无关
/*
 * 加解密数据
 * 
 * 参数 inside - 输入数据,长度任意
 * 参数 outside - 输出数据,长度与输入数据相等
 * 参数 key - AESKEY
 * 参数 ivec - 可读写的一块内存。长度必须是16字节。
 * 参数 enc - 加解密参数,加密: AES_ENCRYPT = 1,解密:AES_DECRYPT = 0
 * 返回值 Unit 
 */
public func aesCfb8Encrypt(inside: Array<UInt8>, outside: Array<UInt8>, key: AESKEY, ivec: Array<UInt8>, enc: Int32): Unit
func aesOfb128Encrypt

注意:

  • OFB128 模式加密和解密均使用 aesSetEncryptKey,这一点比较反常,务必记住。
  • OFB128 模式可一次性加解密。
  • 对于加密解密,每次调用前必须先初始化 ivec 向量, ivec 必须是 16 字节。
  • aesOfb128Encrypt函数既是加密,又是解密。当 inside 为明文时,执行的是加密操作;当 inside 为密文时,执行的是解密操作。
  • OFB128 单词中的 128 属于 Ofb 模式中加解密时分组继续分段的段的大小,与密钥 128 无关
/*
 * 加解密数据
 * 
 * 参数 inside - 输入数据,长度任意
 * 参数 outside - 输出数据,长度与输入数据相等
 * 参数 key - AESKEY
 * 参数 ivec - 可读写的一块内存。长度必须是16字节。
 * 返回值 Unit 
 */
public func aesOfb128Encrypt(inside: Array<UInt8>, outside: Array<UInt8>, key: AESKEY, ivec: Array<UInt8>): Unit
func aesIgeEncrypt

注意:

  • 可一次性加解密。
  • 对于加密解密,每次调用前必须先初始化 ivec 向量, ivec 必须是 32(加密数据块的 2 倍) 字节。
  • 输入数据长度必须是 16 的整数倍
/*
 * 加解密数据
 * 
 * 参数 inside - 输入数据,长度必须是 16 的整数倍
 * 参数 outside - 输出数据,长度与输入数据相等
 * 参数 key - AESKEY
 * 参数 ivec - 可读写的一块内存。长度必须是 32 字节(加密数据块的 2 倍)。
 * 参数 enc - 加解密参数,加密: AES_ENCRYPT = 1,解密:AES_DECRYPT = 0
 * 返回值 Unit 
 */
public func aesIgeEncrypt(inside: Array<UInt8>, outside: Array<UInt8>, key: AESKEY, ivec: Array<UInt8>, enc: Int32): Unit
func aesBiIgeEncrypt

注意:

  • 可一次性加解密。
  • 对于加密解密,每次调用前必须先初始化 ivec 向量, ivec 必须是 64(加密数据块的 4 倍) 字节。
  • 输入数据长度必须是 16 的整数倍
/*
 * 加解密数据
 * 
 * 参数 inside - 输入数据,长度必须是 16 的整数倍
 * 参数 outside - 输出数据,长度与输入数据相等
 * 参数 key - AESKEY
 * 参数 ivec - 可读写的一块内存。长度必须是 64 字节(加密数据块的 4 倍)。
 * 参数 enc - 加解密参数,加密: AES_ENCRYPT = 1,解密:AES_DECRYPT = 0
 * 返回值 Unit 
 */
public func aesBiIgeEncrypt(inside: Array<UInt8>, outside: Array<UInt8>, key: AESKEY, ivec: Array<UInt8>, enc: Int32): Unit
func aesWrapEncrypt

注意:

  • 需设置加密密钥
  • ivec 偏移量必须为 8 字节
  • 输入数据长度必须是 8 的整数倍,且 大于等于 16 位
  • 最小输出缓存区长度 = 输入数据长度 + 8
/*
 * 加解密数据
 * 
 * 参数 key - AESKEY
 * 参数 ivec - 长度必须是 8 字节
 * 参数 outside - 输出数据,等于 输入数据长度 + 8
 * 参数 inside - 输入数据,长度必须是 8 的整数倍,且 大于等于 16 位
 * 返回值 Unit 
 */
public func aesWrapEncrypt(key: AESKEY, ivec: Array<UInt8>, outside: Array<UInt8>, inside: Array<UInt8>): Unit
func aesUnWrapEncrypt

注意:

  • 需设置解密密钥
  • ivec 偏移量必须为 8 字节
  • 输入数据长度必须是 8 的整数倍,且 大于等于 24 位
  • 最小输出缓存区长度 = 输入数据长度 - 8
/*
 * 加解密数据
 * 
 * 参数 key - AESKEY
 * 参数 ivec - 长度必须是 8 字节
 * 参数 outside - 输出数据,等于 输入数据长度 + 8
 * 参数 inside - 输入数据,长度必须是 8 的整数倍,且 大于等于 24 位
 * 返回值 Unit 
 */
public func aesUnWrapEncrypt(key: AESKEY, ivec: Array<UInt8>, outside: Array<UInt8>, inside: Array<UInt8>): Unit
2.3.3 示例
from crypto4cj import aescj.*
from crypto4cj import utils.*
from encoding import hex.*
from std import collection.*
from std import unicode.*

main() {    
    var keys: Array<UInt8> = "1234567812345678".toUtf8Array()
    var inside: Array<UInt8> = "skfhafahglkahglahglkahgalg".toUtf8Array()
    var encodeRes = aesEncode(inside, keys)
    if(toHexString(encodeRes) != "7da4e06948c190ecf633625517c1e7cbd40afb1fbe2dd55438c8f806c1c549d5") {
        return -1
    }

    var decodeRes = aesDecode(encodeRes, keys)
    if(!String.fromUtf8(decodeRes).contains("skfhafahglkahglahglkahgalg")) {
        return -1
    }
    return 0
}

func aesEncode(inside: Array<UInt8>, keys: Array<UInt8>): Array<UInt8> {
    var key = AESKEY()
    var outside: Array<UInt8> = Array<UInt8>(Int64(AES_BLOCK_SIZE), item: 0)

    var keyRet = aesSetEncryptKey(keys, 128, key)

    var data: ArrayList<Array<UInt8>> = arrayTo2Array(inside, Int64(AES_BLOCK_SIZE))
    var res: ArrayList<UInt8> = ArrayList<UInt8>()
    for( i in 0..data.size ) {
        aesEncrypt(data[i], outside, key)
        res.appendAll(outside)
    }   
    return res.toArray()
}

func aesDecode(inside: Array<UInt8>, keys: Array<UInt8>): Array<UInt8> {
    var key = AESKEY()
    var outside: Array<UInt8> = Array<UInt8>(Int64(AES_BLOCK_SIZE), item: 0)

    var keyRet = aesSetDecryptKey(keys, 128, key)

    var data: ArrayList<Array<UInt8>> = arrayTo2Array(inside, Int64(AES_BLOCK_SIZE))
    var res: ArrayList<UInt8> = ArrayList<UInt8>()
    for( i in 0..data.size ) {
        aesDecrypt(data[i], outside, key)
        res.appendAll(outside)
    }   
    return res.toArray()
}

运行结果如下:

0

最后呢

很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

在这里插入图片描述

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细鸿蒙(OpenHarmony )手册(共计1236页)与鸿蒙(OpenHarmony )开发入门视频,帮助大家在技术的道路上更进一步。

  • 《鸿蒙 (OpenHarmony)开发学习视频》
  • 《鸿蒙生态应用开发V2.0白皮书》
  • 《鸿蒙 (OpenHarmony)开发基础到实战手册》
  • OpenHarmony北向、南向开发环境搭建
  • 《鸿蒙开发基础》
  • 《鸿蒙开发进阶》
  • 《鸿蒙开发实战》

在这里插入图片描述

总结

鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行! 自↓↓↓拿

  • 10
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RC2是由著名密码学家Ron Rivest设计的一种传统对称分组加密算法,它可作为DES算法的建议替代算法。它的输入和输出都是64比特。密钥的长度是从8字节到128字节可变,但目前的实现是8字节(1998年)。 此算法被设计为可容易地在16位的微处理器上实现。在一个IBM AT机上,RC2加密算法的执行可比DES算法快两倍(假设进行密钥扩展)。在C#中用RC2CryptoServiceProvider可以实现此算法。 算法原理: 1.根据计算机cpu序列号 ,硬盘ID,网卡硬件地址 号生成注册码: //获取机器码 public static string getMachineCode() { string machineCode = ""; MD5CryptoServiceProvider provider1; byte[] array1; string text1; string text2; byte num1; byte[] array2; int num2; provider1 = new MD5CryptoServiceProvider(); string cpuInfo = "";//cpu序列号 ManagementClass cimobject = new ManagementClass("Win32_Processor"); ManagementObjectCollection moc = cimobject.GetInstances(); foreach (ManagementObject mo in moc) { cpuInfo += mo.Properties["ProcessorId"].Value.ToString(); } //获取硬盘ID string HDid = ""; ManagementClass cimobjectHDid = new ManagementClass("Win32_DiskDrive"); ManagementObjectCollection mocHDid = cimobjectHDid.GetInstances(); foreach (ManagementObject mo in mocHDid) { HDid += (string)mo.Properties["Model"].Value; } //获取网卡硬件地址 string strMac = ""; ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection mocMac = mc.GetInstances(); foreach (ManagementObject mo in mocMac) { if ((bool)mo["IPEnabled"] == true) strMac += mo["MacAddress"].ToString(); mo.Dispose(); } array1 = provider1.ComputeHash(Encoding.Default.GetBytes(cpuInfo + strMac)); text1 = "ENTOPYMICROSYSTEMSDEVINIMMUHENDISLIK231456789ACD23456789AEFABGHJKLMNPRSTUVWYZXAHMETALIAKKASHAKANESKICI"; text2 = string.Empty; array2 = array1; for (num2 = 0; (num2 < array2.Length); num2 = (num2 + 1)) { num1 = array2[num2]; text2 = string.Concat(text2, text1.Substring((num1 % text1.Length), 1)); } machineCode = text2.Substring(0, 10); return machineCode; } 2.根据注册码按照RC2生成注册码: //根据算法得到注册码 public static string getRegisterCode(string machineCode,string _configName) { string computeCode = ""; byte[] array1, array2, array3, array4; MemoryStream stream1 = new MemoryStream(); BinaryFormatter formatter1 = new BinaryFormatter(); formatter1.Serialize(stream1, machineCode); array1 = stream1.ToArray(); RC2CryptoServiceProvider provider11 = new RC2CryptoServiceProvider(); provider11.KeySize = 128; #region byte[] str1 = new byte[8] ; byte[] str2 = new byte[16] ; DataTable dt = Xml.GetAllDataFromXml("Config.xml"); if (dt != null && dt.Rows.Count > 0) { foreach(DataRow dr in dt.Rows) { if (dr[1].ToString() == _configName) { str1 = new byte[] { byte.Parse(dr[2].ToString()), byte.Parse(dr[3].ToString()), byte.Parse(dr[4].ToString()), byte.Parse(dr[5].ToString()), byte.Parse(dr[6].ToString()), byte.Parse(dr[7].ToString()), byte.Parse(dr[8].ToString()), byte.Parse(dr[9].ToString()) }; str2 = new byte[] { byte.Parse(dr[10].ToString()), byte.Parse(dr[11].ToString()), byte.Parse(dr[12].ToString()), byte.Parse(dr[13].ToString()), byte.Parse(dr[14].ToString()), byte.Parse(dr[15].ToString()), byte.Parse(dr[16].ToString()), byte.Parse(dr[17].ToString()), byte.Parse(dr[18].ToString()), byte.Parse(dr[19].ToString()), byte.Parse(dr[20].ToString()), byte.Parse(dr[21].ToString()), byte.Parse(dr[22].ToString()), byte.Parse(dr[23].ToString()),byte.Parse(dr[24].ToString()),byte.Parse(dr[25].ToString()) }; break; } } } #endregion array2 =str1 ; array3 = str2 ; provider11.IV = array2; provider11.Key = array2; ICryptoTransform transform1 = provider11.CreateEncryptor(); stream1 = new MemoryStream(); CryptoStream stream2 = new CryptoStream(stream1, transform1, System.Security.Cryptography.CryptoStreamMode.Write); try { stream2.Write(array1, 0, array1.Length); stream2.FlushFinalBlock(); array4 = stream1.ToArray(); } finally { stream1.Close(); stream2.Close(); } stream1 = new MemoryStream(); formatter1.Serialize(stream1, array4); computeCode = Convert.ToBase64String(stream1.ToArray()).Trim(); return computeCode; } 3.check public static bool checkRegisterCode(string machineCode, string registerCode,string configName) { string computeCode = getRegisterCode(machineCode, configName); if (computeCode == registerCode) { return true; } else return false; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值