MetaAccess
Introduction
MetaAccess 用于为提供一个去中心化的授权功能,让链上的加密数据,按照特定规则授权查看。
Spec
约定需要两个协议,AccessControl和AccessPass。
AccessControl负责设置权限进行控制,在发布密文内容的同时也发布AccessControl上链。
AccessPass负责构建付费和授权交易,用于授权展示明文内容
AccessControl
path: /metaaccess/accesscontrol
{
"publicContent": "public part of content",//公开部分内容
"publicPins":["PINID-1", "PINID-2"],//公开部分文件
"publicPath": "/protocols/simplepublicbuzz",
"controlPins":["PINID1","PINID2"], //Array of PINs that will be in control of accessing
"controlPath": "/protocols/simpleasseccbuzz",//The pins which is in this path will be in control of accessing
"manDomain":"",//待定
"manPubkey":"THE-PUBKEY-OF-MAN", //Pubkey of the MAN node providing custody decryption services.
"creatorPubkey":"THE-PUBKEY-OF-CREATOR",//Pubkey of the creator
"encryptedKey":"Use the ECDH Key to Decrypt it and use that decryptedkey to decrypt the content",
"holdCheck":{//hold检查
"type":"mrc20" //"chainCoin" or "mrc20",
"ticker":"mc" //the ticker of mrc20;if type = chainCoin then it will be ignored
"amount":"1000"
},
"payCheck":{//pay检查
"type":"chainCoin", //"chainCoin" or "mrc20"
"ticker":"",
"amount":"0.00001",
"payTo":"address",
"validPeriod": "4320", //blocks,4320 means 1 month
},
}
AccessPass
path: /metaaccess/accesspass
{
"accessControlID":"the-pinid-of-accesscontrol-file"
}
流程
创作者:
应用端请求MAN获取publicKey,此时MAN会针对该请求生成一对公私钥并保存,然后返回man-publicKey
应用端对钱包请求ecdh操作,根据传的钱包路径和man-publicKey,生成协商密钥SP
应用端生成随机AES密钥-P1
应用端编辑文本或图片,选择公开部分和付费部分,设置付费模式
使用密钥-P1对付费部分内容进行AES加密,即对整个payload进行加密,得到内容txRaw
使用协商密钥SP对密钥-P1进行AES加密,得到encrypted-key,构建
accesscontrol
的pin把内容pin和
accesscontrol
的pin统一广播上链
购买者:
应用端构建
accesspass
,output中带有针对accesscontrol
所指定的paymentMAN提供获取密文的接口,需要带钱包的头部签名信息,MAN验证签名信息,获取带签名地址的
accesspass
MAN根据accessControlID查询对应的
accesscontrol
,用man-privateKey与creator-publicKey生成协商密钥SPMAN先判断
accesspass
是否符合accesscontrol
,符合进行下一步,不符合则返回空用协商密钥SP对encrypted-key解密,获取密钥-P1
MAN用密钥-P1解密对应的controlPins,返回明文内容
ECDH 配置说明
为了确保客户端与服务器端在密钥交换过程中能够正常协作,双方在 ECDH (Elliptic Curve Diffie-Hellman) 密钥交换协议中需要统一以下配置参数:
椭圆曲线类型
使用的曲线:
NIST P-256
(即secp256r1
或prime256v1
)。P-256
是一种被广泛使用的椭圆曲线,兼具较好的安全性和效率。
公钥和私钥格式
私钥和公钥均以 Hex 编码 的字符串形式进行传输。
公钥在传输前通过
PublicKey().Bytes()
转换为字节数组,再进行 Hex 编码;私钥同样通过Bytes()
转换为字节数组再 Hex 编码。
密钥派生
双方各自生成公私钥对后,使用私钥和对方的公钥计算共享密钥。
共享密钥在计算完成后可以直接用于对称加密的密钥材料。
对称加密配置 (AES)
对称加密算法
使用
AES-256-CFB
模式作为对称加密算法。CFB (Cipher Feedback)
模式支持流式加密和解密,适合在共享密钥环境下进行数据加密。
AES 密钥生成
采用 256 位(32 字节)的随机字节作为 AES 密钥,生成时通过
rand.Read
随机生成。AES 密钥使用 Hex 编码存储和传输。
初始化向量 (IV)
每次加密操作生成新的 16 字节(AES 块大小)的随机初始化向量(IV)。
IV 放在密文的前面一起传输,解密时需要从密文中提取 IV。
Go代码示例:
// 生成 ECDH 密钥对
func GenKeyPair() (privateKey string, publicKey string, e error) {
curve := ecdh.P256()
privKeyA, err := curve.GenerateKey(rand.Reader)
if err != nil {
return
}
privateKey = hex.EncodeToString(privKeyA.Bytes())
publicKey = hex.EncodeToString(privKeyA.PublicKey().Bytes())
return
}
// 密钥交换过程
func PerformECDH(privKeyA *ecdh.PrivateKey, pubKeyB *ecdh.PublicKey) ([]byte, error) {
return privKeyA.ECDH(pubKeyB) // 生成共享密钥
}
// 生成 AES 密钥
func GenerateAESKey() (string, error) {
key := make([]byte, 32) // AES-256 key
_, err := rand.Read(key)
if err != nil {
return "", err
}
return hexEncode(key), nil
}
// AES 加密
func EncryptPayloadAES(key, payload []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
ciphertext := make([]byte, aes.BlockSize+len(payload))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(ciphertext[aes.BlockSize:], payload)
return ciphertext, nil
}
Last updated