# Runes - Simple Cookies You Can Extend (similar to Macaroons)
https://research.google/pubs/pub41892/ is a paper called "Macaroons:
Cookies with Contextual Caveats for Decentralized Authorization in the
Cloud". It has one good idea, some extended ideas nobody implements,
and lots and lots of words.
The idea: a server issues a cookie to Alice. She can derive cookies
with extra restrictions and hand them to Bob and Carol to send back to
the server, and they can't remove the restrictions.
But they did it using a Message Authetication Code (MAC, get it?),
which is actually counter-productive, since it's simpler and better to
use Length Extension to achieve the same results. I call that a Rune;
this version really only handles strings, but you can use hex or another
encoding.
## Rune Language
A *rune* is a series of restrictions; you have to pass all of them (so
appending a new one always makes the rune less powerful). Each
restriction is one or more alternatives ("cmd=foo OR cmd=bar"), any
one of which can pass.
The form of each alternative is a simple string:
ALTERNATIVE := FIELDNAME CONDITION VALUE
`FIELDNAME` contains only UTF-8 characters, exclusive of
! " # $ % & ' ( ) * +, - . / : ; ? @ [ \ ] ^ _ \` { | } ~ (C's ispunct()).
These can appear inside a `VALUE`, but `&`, `|` and `\\` must be escaped with `\` (escaping is legal for any character, but unnecessary).
`CONDITION` is one of the following values:
* `!`: Pass if field is missing (value ignored)
* `=`: Pass if exists and exactly equals
* `^`: Pass if exists and begins with
* `$`: Pass if exists and ends with
* `~`: Pass if exists and contains
* `<`: Pass if exists, is a valid decimal (may be signed), and numerically less than
* `>`: Pass if exists, is a valid decimal (may be signed), and numerically greater than
* `}`: Pass if exists and lexicograpically greater than (or longer)
* `{`: Pass if exists and lexicograpically less than (or shorter)
* `#`: Always pass: no condition, this is a comment.
Grouping using `(` and `)` may be added in future.
A restriction is a group of alternatives separated by `|`; restrictions
are separated by `&`.
e.g.
cmd=foo | cmd=bar
& subcmd! | subcmd{get
The first requires `cmd` be present, and to be `foo` or `bar`. The second
requires that `subcmd` is not present, or is lexicographically less than `get`.
Both must be true for authorization to succeed.
## Rune Authorization
A run also comes with a SHA-256 authentication code. This is
generated as SHA-256 of the following bytestream:
1. The secret (less than 56 bytes, known only to the server which issued it).
2. For every restriction:
1. Pad the stream as per SHA-256 (i.e. append 0x80, then zeroes, then
the big-endian 64-bit bitcount so far, such that it's a multiple of 64
bytes).
2. Append the restriction.
By using the same padding scheme as SHA-256 usually uses to end the
data, we have the property that we can initialize the SHA-256 function
with the result from any prior restriction, and continue.
The server can validate the rune authorization by repeating this
procedure and checking the result.
## Rune Encoding
Runes are encoded as base64, starting with the 256-bit SHA256
authentication code, the followed by one or more restrictions
separated by `&`.
Not because base64 is good, but because it's familiar to Web people;
we use RFC3548 with `+` and `/` replaced by `-` and `_` to make
it URL safe.
## API Example
Here's the server, making you a rune! (spoiler: it's
"-YpZTBZ4Tb5SsUz3XIukxBxR619iEthm9oNJnC0LxZM=")
```
import runes
import secrets
# Secret determined by fair dice roll.
secret = bytes([5] * 16)
# Make an unrestricted rune.
rune = runes.MasterRune(secret)
# We could add our own restrictions here, if we wanted.
print("Your rune is {}".format(rune.to_base64()))
```
Here's the server, checking a rune. You will need to define what
conditions you provide for the rune to test; one of the most useful
ones is time, but other common things are the resource being accessed,
(e.g. URL, or command and parameters), or who is accessing it (assuming
you have authenticated them already in some way).
```
import runes
import time
import sys
secret = bytes([5] * 16)
# In real life, this would come from the web data.
runestring = sys.argv[1]
# This checks the format is correct, it's authorized, an that it meets
# our values. I assume we have values time (UNIX, seconds since
# 1970), command and optional id.
# (You can also use rune.check() if you don't care *why* it failed)
ok, whyfail = rune.check_with_reason(secret, runestring,
{'time': int(time.time()),
'command': 'somecommand',
'id': 'DEADBEEF'})
if not ok:
print("Rune restrictions failed: {}".format(whyfail))
sys.exit(1)
print("Yes, you passed!")
```
Here's the client Alice. She gets the rune and gives Bob a variant
that can only be used for 1 minute:
```
import runes
import time
# In real life, this would come from the web data.
runestring = sys.argv[1]
# You'd catch exceptions here, usually.
rune = runes.from_base64(runestring)
# You can construct a Restriction class from a sequence of Alternative
# but it's easier to use decode() to translate a string
rune.add_restriction(rune.Restriction.decode("time < {}".format((int)time.time() + 60))
print("Your restricted rune is {}".format(rune.to_base64()))
```
You can find more examples in the examples/ subdirectory.
## Author
Rusty Russell wrote it; but I blame @roasbeef for raving about them
long enough at LnConf that I actually read the paper. It only took me
18 months to find a day to implement them.
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
共10个文件
txt:4个
pkg-info:2个
zip-safe:1个
资源分类:Python库 所属语言:Python 资源全名:runes-0.3.1.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
资源推荐
资源详情
资源评论
收起资源包目录
runes-0.3.1.tar.gz (10个子文件)
runes-0.3.1
PKG-INFO 7KB
runes.egg-info
PKG-INFO 7KB
requires.txt 7B
SOURCES.txt 186B
top_level.txt 1B
dependency_links.txt 1B
zip-safe 1B
setup.cfg 38B
setup.py 1KB
README.md 6KB
共 10 条
- 1
资源评论
挣扎的蓝藻
- 粉丝: 13w+
- 资源: 15万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 详解protobuf-c之在C语言中如何使用repeated生成数组和字符串(包含配置pb-callback-t)
- Python 程序语言设计模式思路-并发模式:消费者模式:协调生产者和消费者之间的数据交换
- pythonA*算法(A-star algorithm),寻路算法
- guitest.zip
- udp_echo.v
- udp_echo_server.v
- python双向广度优先搜索算法(Bidirectional Breadth-First Search, BBFS),寻路算法
- python迭代加深算法(Iterative Deepening Depth-First Search, IDDFS),寻路算法
- 京东商品链接采集助手 2024版
- 基于Java的ApplicationPower快速项目生成脚手架设计源码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功