Golang动态码MFA

背景概述

当我们对系统进行操作时,往往需要MFA验证码,处于安全考虑MFA又不能给其他人使用,为此我们需要一个工具来提供FMA码给其他人使用。

概念

那么什么是OTP呢? 一次性密码(One Time Password),简称OTP,是只能使用一次的密码。 每次做身份认证时都会生成一个新的密码,在使用一次之后立即失效,不能重复使用。 这种密码只能使用一次,因此即使攻击者能够窃取到密码,也无法再次使用该密码进行身份认证。

参考资料

  • kubePi
  • gotp

需求实现

生成动态码

这里我们利用已有系统来生成动态码,例如我们的JumpServer,那么我们如何拿到这个secret呢,我们可以将我们的动态码导出来,然后打开文件即可。

图片image-20241011140558736图片image-20241011140714033

代码案例

package main

import (
 "fmt"
 "github.com/xlzd/gotp"
)

func main() {
 d, _ := GetCode("anRuo")
 fmt.Println(d)

}


type Otp struct {
 Secret  string `json:"secret"`
 QrImage string `json:"qrImage"`
 Code    string `json:"code"`
}

// 直接生成验证码

func GetCode(username string) (otp Otp, err error) {
 secret := "111111111111"
 otp.Secret = secret
 totp := gotp.NewDefaultTOTP(secret)
 otp.Code = totp.Now()
 return otp, nil
}

这样我们就可以将动态码拿到了,然后结合我们的工单系统来实现动态码的申请。

实现动态码

这里我们借鉴JumpServer的实现方式,将动态码转为图片的形式。

package main

import (
 "bytes"
 "encoding/base64"
 "fmt"
 "github.com/skip2/go-qrcode"
 "github.com/xlzd/gotp"
)

func main() {
 data, _ := GetOtp("www.kubesre.com")
 fmt.Println(data)

}

type Otp struct {
 Secret  string `json:"secret"`
 QrImage string `json:"qrImage"`
 Code    string `json:"code"`
}

func GetOtp(username string) (otp Otp, err error) {
 secret := "1111111111"
 gotp.RandomSecret(16)
 otp.Secret = secret
 totp := gotp.NewDefaultTOTP(secret)
 uri := totp.ProvisioningUri(username, "anRuo")
 subImg, err := qrcode.Encode(uri, qrcode.Medium, 256)
 dist := make([]byte, 3000)
 base64.StdEncoding.Encode(dist, subImg)
 index := bytes.IndexByte(dist, 0)
 baseImage := dist[0:index]
 otp.QrImage = "data:image/png;base64," + string(baseImage)
 return otp, err
}

此时我们就可以将动态码转为图片,然后再结合MFA扫码进行绑定了。

图片image-20241011144654499图片image-20241011144742120

总结

到此我们就大致实现了如何给内部系统添加动态码,以及如何生成动态码了,如果你有更好的方式,欢迎一起交流。

posted @ 2024-10-11 15:21  技术颜良  阅读(12)  评论(0编辑  收藏  举报