对可验证秘密共享的简单介绍

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对可验证秘密共享的简单介绍相关的知识,希望对你有一定的参考价值。

参考技术A

最近FATE开源社区分享了「 基于FATE实现的可验证秘密共享算法 」一文(后简称实现),介绍了光大科技在联邦学习技术实践过程中,针对跨机构数据统计这一场景,实践了可验证秘密共享(Verifiable Secret Sharing)的安全多方隐私求和方案,能够在数据不出本地的情况下,对多个机构的数据求和。

按照原文介绍可知,该场景是对Shamir秘密共享 和 可验证秘密共享的综合应用(整体方案参见原文)。

这里对文中涉及的可验证秘密共享做一个简单说明。

可验证秘密共享(Verifiable Secret Share, VSS)的概念由 Benny Chor、Shafi Goldwasser、Silvio Micali 和 Baruch Awerbuch 于 1985 年首次提出:如果参与方可以使用辅助信息验证其他参与方秘密共享内容的 一致性 ,那么该秘密共享方案就是可验证的。 可验证的秘密共享确保了即使某参与方是恶意的,也必须有一个明确定义的秘密(遵循协议设定),其他参与方稍后可以恢复秘密值。

注:经典的Shamir秘密共享方案中,假参与方是诚实的。

可验证的秘密共享对于安全多方计算来说还是很重要的。 我们知道,安全多方计算通常是通过对输入进行秘密共享并操作共享来计算某些函数完成的。 为了应对可能“捣乱”的参与方,可以对秘密共享的安全性进行增强,额外添加验证操作,防止(或及早发现)这些参与方的偏离协议行为。

下文对Feldman的可验证秘密共享方案进行简单说明。

Feldman VSS是一个常见的可验证秘密共享方案,由 Paul Feldman 提出(参见其论文:「A Practical Scheme for Non-interactive Verifiable Secret Sharing」);它在 Shamir 秘密共享之上结合了同态加密方案。

该方案中首先选取一个素数( )阶的循环群 以及 的生成元 , 这些会公开作为系统参数。 选择适合的循环群 以保证其上离散对数计算的困难性。 通常,可以选择 的 阶子群,其中 是素数, 且 整除 。

然后处理方生成一个 次随机多项式 ,其系数在 中选取,且 (即是秘密值)。 个参与方中的每一个都将收到一个值 。 任何 个秘密分享的持有者都可以使用多项式插值模 恢复秘密 (但任何最多 个持有者们都不能恢复秘密值)。

以上基本是Shamir秘密共享方案。为了使这些共享可以验证,参与方需要分发 多项式系数模 作为承诺(commitment)。

比如, ,那么必须给出的承诺是:

一旦给出这些,任何一方都可以验证他们的得到的秘密分享。 例如,为了验证 ,如:

注意,方案中涉及两个素数,再稍作说明。

需要选择两个素数 ,满足 ,他们分别应用在不同的计算上:

选择如下参数:

则计算一个秘密共享为 ,对应的承诺为

可以验证

综上,VSS主要是对共享内容的一致性进行验证,保证其内容是遵循方案协议的;至于参与计算的内容是否真实有效,就不在验证范围内了。

对于秘密分享,有很多方案;除了Shamir秘密共享,还有Additive Secret Share、SPDZ、基于中国剩余定理的方案等等。

对于VSS,常见的还有Benaloh方案。

后续再做跟进整理。

跨命名空间共享秘密

【中文标题】跨命名空间共享秘密【英文标题】:Sharing secret across namespaces 【发布时间】:2018-02-28 02:12:28 【问题描述】:

有没有办法在 Kubernetes 中?

我的用例是:我的所有命名空间都有相同的私有注册表,我想避免为每个命名空间创建相同的秘密。

【问题讨论】:

这会自动分享秘密:github.com/zakkg3/ClusterSecret 【参考方案1】:

Secret API 对象位于命名空间中。它们只能被同一命名空间中的 pod 引用。基本上,您必须为每个命名空间创建秘密。

https://kubernetes.io/docs/concepts/configuration/secret/#details

【讨论】:

配置映射相同。 kubernetes.io/docs/tasks/configure-pod-container/… 这是正确的答案,值得一提的是,您可以通过 kubectl + sed 克隆到另一个命名空间,全部在一行中,请参阅下面的答案。【参考方案2】:

它们只能被同一命名空间中的 pod 引用。但是您可以将秘密从一个名称空间复制到另一个名称空间。下面是一个将 localdockerreg 秘密从 default 命名空间复制到 dev 的示例:

kubectl get secret localdockerreg --namespace=default --export -o yaml | kubectl apply --namespace=dev -f -

###更新### 在 Kubernetes v1.14 中,--export 标志是 deprecated。因此,以下带有-oyaml 标志的命令将在即将发布的版本中正常工作。

kubectl get secret localdockerreg --namespace=default -oyaml | kubectl apply --namespace=dev -f -

如果源命名空间不一定是默认的,则低于或低于

kubectl get secret localdockerreg --namespace=default -oyaml | grep -v '^\s*namespace:\s' | kubectl apply --namespace=dev -f -

【讨论】:

如果您要导出的机密不在默认命名空间中,这将不起作用 适用于我在 v1.13 上的任何两个命名空间 嗯,当我使用第二个命令(没有 --export 标志)时,我收到一条错误消息,提示“提供的选项中的命名空间不匹配”。 kubectl 版本 1.15。我认为您可能需要在这两个 kubectl 命令之间使用 sed 或其他东西来从输出 yaml 中删除命名空间 准确来说,需要从中间 YAML 中移除源命名空间:$ kubectl get secret <SECRET> --namespace <NS-SRC> -oyaml | grep -v '^\s*namespace:\s' | kubectl apply --namespace <NS-DST> -f - p.s.未使用其他对象类型进行测试,但应该可以工作 p.p.s.如果您要移动,请不要忘记删除源 工作,如果在集群之间使用 kubectl 更改上下文,则使用上下文【参考方案3】:

接受的答案是正确的:Secrets 只能被同一命名空间中的 pod 引用。因此,如果您希望自动化“同步”或只是在命名空间之间复制秘密,这里有一个提示。

自动化(操作员)

要在命名空间之间自动共享或同步秘密,请使用 ClusterSecret 运算符:

https://github.com/zakkg3/ClusterSecret

使用 sed:

kubectl get secret <secret-name> -n <source-namespace> -o yaml \
| sed s/"namespace: <source-namespace>"/"namespace: <destination-namespace>"/\
| kubectl apply -n <destination-namespace> -f -

使用jq

如果你有 jq,我们可以使用@Evans Tucker 解决方案

kubectl get secret cure-for-covid-19 -n china -o json \
 | jq 'del(.metadata["namespace","creationTimestamp","resourceVersion","selfLink","uid"])' \
 | kubectl apply -n rest-of-world -f -

【讨论】:

有一些元数据在移植秘密时应该被删除,见Evans answer 为此您必须安装 jq,并且在某些情况下这是不可能的。但我也添加了这个选项,谢谢马特! 不用担心,我只是想为第一次看到这个答案的人强调两个答案之间的功能差异 我的评论也应该说“可能要删除”,因为保留源元数据也很有用【参考方案4】:

Secret 是命名空间资源,但您可以使用 Kubernetes 扩展来复制它们。我们使用它来将存储在秘密中的凭据或证书自动传播到所有命名空间并保持同步(修改源并更新所有副本)。 请参阅 Kubernetes 反射器 (https://github.com/EmberStack/kubernetes-reflector)。

该扩展允许您通过注释自动复制和保持跨命名空间的秘密:

在源密钥上添加注释:

 annotations:
   reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"

这将在所有命名空间中创建密钥的副本。您可以使用以下方法限制创建副本的命名空间:

reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "namespace-1,namespace-2,namespace-[0-9]*"

该扩展也支持 ConfigMaps 和 cert-manager 证书。 免责声明:我是 Kubernetes Reflector 扩展的作者。

【讨论】:

【参考方案5】:

--export 已弃用

sed 不是编辑 YAML 或 JSON 的合适工具。

这是一个使用jq 删除我们不想要的命名空间和其他元数据的示例:

kubectl get secret cure-for-covid-19 -n china -o json \
 | jq 'del(.metadata["namespace","creationTimestamp","resourceVersion","selfLink","uid"])' \
 | kubectl apply -n rest-of-world -f -

【讨论】:

这应该是第一个解释命名空间的使用和技术的第二个答案。如果你来这里是想将秘密复制到一个新的命名空间,请使用这个。【参考方案6】:

Another option would be to use kubed,由 Jetstack 的好心人推荐,他们给了我们证书管理器。 Here is what they link to.

【讨论】:

【参考方案7】:

正如 Innocent Anigbo 所回答的,您需要在同一个命名空间中拥有秘密。如果您需要动态支持或避免忘记创建秘密,则可以为命名空间对象 https://kubernetes.io/docs/admin/extensible-admission-controllers/ 创建一个初始化程序(我自己没有这样做,所以不能确定)

【讨论】:

【参考方案8】:

从@NicoKowe改进

一个班轮将所有秘密从一个命名空间复制到另一个命名空间

$ for i in `kubectl get secrets | awk 'print $1'`; do  kubectl get secret $1 -n <source-namespace> -o yaml | sed s/"namespace: <source-namespace>"/"namespace: <target-namespace>"/ | kubectl apply -n <target-namespace> -f -  ; done

【讨论】:

【参考方案9】:

基于@Evans Tucker 的回答,但在 jq 过滤器中使用白名单而不是删除来只保留我们想要的。

kubectl get secret cure-for-covid-19 -n china -o json | jq 'apiVersion,data,kind,metadata,type | .metadata |= "annotations", "name"' | kubectl apply -n rest-of-world -f -

基本相同,但保留标签。

kubectl get secret cure-for-covid-19 -n china -o json | jq 'apiVersion,data,kind,metadata,type | .metadata |= "annotations", "name", "labels"' | kubectl apply -n rest-of-world -f -

【讨论】:

【参考方案10】:

使用 RBAC 授权 serviceaccoun 使用原始命名空间上的密钥。但是,不建议在命名空间之间使用共享密钥。

【讨论】:

【参考方案11】:

复制所有秘密的解决方案。

kubectl delete secret --namespace $TARGET_NAMESPACE--all;
kubectl get secret --namespace default --output yaml \
    | sed "s/namespace: $SOURCE_NAMESPACE/namespace: $TARGET_NAMESPACE/" \
    | kubectl apply --namespace $TARGET_NAMESPACE --filename -;

【讨论】:

【参考方案12】:

yq 是用于编辑 YAML 文件的有用命令行工具。我将它与其他答案结合使用来得到这个:

kubectl get secret <SECRET> -n <SOURCE_NAMESPACE> -o yaml | yq write - 'metadata.namespace' <TARGET_NAMESPACE> | kubectl apply -n <TARGET_NAMESPACE> -f -

【讨论】:

请注意,这是针对 yq kubectl get secret <SECRET> -n <SOURCE_NAMESPACE> -o yaml | yq eval '.metadata.namespace = "<TARGET_NAMESPACE>"' - | kubectl apply -n <TARGET_NAMESPACE> -f -【参考方案13】:

您也可以考虑使用GoDaddy's Kubernetes External Secrets!您将在 AWS Secret Manager (ASM) 中存储您的秘密,GoDaddy 的秘密控制器将自动创建这些秘密。此外,ASM 和 K8S 集群之间会有同步。

【讨论】:

【参考方案14】:

kubectl 获取秘密 gitlab-registry --namespace=revsys-com --export -o yaml |\ kubectl apply --namespace=devspectrum-dev -f -

【讨论】:

以上是关于对可验证秘密共享的简单介绍的主要内容,如果未能解决你的问题,请参考以下文章

基于FATE的可验证秘密分享算法详解及应用场景分享:学习

CentOS上搭建Samba服务器简单介绍

自定义验证规则以及中间件简单介绍

java多线程(简单介绍)

安全多方计算之六:秘密共享

安全多方计算之六:秘密共享