Pure Go Kerberos library for clients and services

gokrb5

It is recommended to use the latest version: Version

Development will be focused on the latest major version. New features will only be targeted at this version.

Versions Dependency Management Import Path Usage Godoc Go Report Card
v8 Go modules import "github.com/jcmturner/gokrb5/v8/{sub-package}" Usage GoDoc Go Report Card
v7 gopkg.in import "gopkg.in/jcmturner/gokrb5.v7/{sub-package}" Usage GoDoc Go Report Card

Go Version Support

Go version Go version

gokrb5 may work with other versions of Go but they are not formally tested. It has been reported that gokrb5 also works with the gollvm compiler but this is not formally tested.

Features

  • Pure Go - no dependency on external libraries
  • No platform specific code
  • Server Side
    • HTTP handler wrapper implements SPNEGO Kerberos authentication
    • HTTP handler wrapper decodes Microsoft AD PAC authorization data
  • Client Side
    • Client that can authenticate to an SPNEGO Kerberos authenticated web service
    • Ability to change client's password
  • General
    • Kerberos libraries for custom integration
    • Parsing Keytab files
    • Parsing krb5.conf files
    • Parsing client credentials cache files such as /tmp/krb5cc_$(id -u $(whoami))

Implemented Encryption & Checksum Types

Implementation Encryption ID Checksum ID RFC
des3-cbc-sha1-kd 16 12 3961
aes128-cts-hmac-sha1-96 17 15 3962
aes256-cts-hmac-sha1-96 18 16 3962
aes128-cts-hmac-sha256-128 19 19 8009
aes256-cts-hmac-sha384-192 20 20 8009
rc4-hmac 23 -138 4757

The following is working/tested:

  • Tested against MIT KDC (1.6.3 is the oldest version tested against) and Microsoft Active Directory (Windows 2008 R2)
  • Tested against a KDC that supports PA-FX-FAST.
  • Tested against users that have pre-authentication required using PA-ENC-TIMESTAMP.
  • Microsoft PAC Authorization Data is processed and exposed in the HTTP request context. Available if Microsoft Active Directory is used as the KDC.

Contributing

If you are interested in contributing to gokrb5, great! Please read the contribution guidelines.


References

Useful Links

Thanks

  • Greg Hudson from the MIT Consortium for Kerberos and Internet Trust for providing useful advice.

Contributing

Thank you for your interest in contributing to gokrb5 please read the contribution guide as it should help you get started.

Known Issues

Issue Worked around? References
The Go standard library's encoding/asn1 package cannot unmarshal into slice of asn1.RawValue Yes https://github.com/golang/go/issues/17321
The Go standard library's encoding/asn1 package cannot marshal into a GeneralString Yes - using https://github.com/jcmturner/gofork/tree/master/encoding/asn1 https://github.com/golang/go/issues/18832
The Go standard library's encoding/asn1 package cannot marshal into slice of strings and pass stringtype parameter tags to members Yes - using https://github.com/jcmturner/gofork/tree/master/encoding/asn1 https://github.com/golang/go/issues/18834
The Go standard library's encoding/asn1 package cannot marshal with application tags Yes
The Go standard library's x/crypto/pbkdf2.Key function uses the int type for iteraction count limiting meaning the 4294967296 count specified in https://tools.ietf.org/html/rfc3962 section 4 cannot be met on 32bit systems Yes - using https://github.com/jcmturner/gofork/tree/master/x/crypto/pbkdf2 https://go-review.googlesource.com/c/crypto/+/85535
Owner
Comments
  • "SID revision value read as 4 when it must be 1"

    Hey,

    I have a SPNEGO flow that worked fine for some user but suddenly I started to get this error:

    SID revision value read as 4 when it must be 1

    In parallel I tried with other user and it worked fine, but i'm not sure what causing the SID.revision to be 4 instead of 1 for a specific user (tried purging klist ticket, etc... nothing works) Any clue what could have caused this ? Microsoft papers don't say much except that revision value in SID should be 0x1 but it is not and I'm a bit clueless,

    Thanks,

    Asaf.

  • ClientClaimsInfo error parsing byte stream headers: Malformed NDR steam: Not enough bytes.

    ClientClaimsInfo error parsing byte stream headers: Malformed NDR steam: Not enough bytes.

    Hi,

    We use this library as part of https://github.com/wintoncode/vault-plugin-auth-kerberos.

    We have a working setup that accepts kerberos ticket issued on linux host. However when we run with tickets issued from our windows 10 boxes we get ClientClaimsInfo error. Both windows and linux machines are on the same domain.

    A bit more background around the kerberos ticket generated on linux and windows: Windows kerberos token as python string:

    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
    

    Linux Kerberos token as python string:

    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
    

    We will add more info once we get them. Just keen to get this going.

    Thanks.

  • KDC_ERR_PREAUTH_FAILED after certain amount of time

    KDC_ERR_PREAUTH_FAILED after certain amount of time

    Hi, Everything works perfect for approximately 24 hours, after that period the following error starts to appear. could not get service ticket: [Root cause: KDC_Error] KDC_Error: AS Exchange Error: kerberos error response from KDC: KRB Error: (24) KDC_ERR_PREAUTH_FAILED Pre-authentication information was invalid After restarting the service everything works normal again. Any help is appreciated.

  • OID of MechToken does not match the first in the MechTypeList?

    OID of MechToken does not match the first in the MechTypeList?

    Hello! I am little bit confused and need some advice.

    In my Golang (version go1.11.5 linux/amd64) application I am trying to use this library to create SSO (single sign on) authorization by Kerberos and Active Directory.

    I have several things:

    1. SPN name for my microservice.
    2. krb5.keytab for my microservice.
    3. krb5.conf file for kerberos client where I set REALM and KDC information.

    As you can see my main.go file looks pretty simple:

    func main() {
        l := log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile)
    
        kt, err := keytab.Load("./configurations/krb5.keytab"); if err != nil {
            l.Fatalf("Error on \"keytab.Load\": %v", err)
        }
    
        mux := http.NewServeMux()
    
        mux.Handle("/", spnego.SPNEGOKRB5Authenticate(http.HandlerFunc(controllers.GetInformation), kt, service.Logger(l)))
    
        log.Fatal(http.ListenAndServe(":8000", mux))
    }
    

    This code raise such ERROR:

    2019/04/11 20:07:54 spnego.go:95: 172.28.88.133:2359 - SPNEGO validation error: defective token detected: OID of MechToken does not match the first in the MechTypeList
    2019/04/11 20:07:54 spnego.go:95: 172.28.88.133:2359 - SPNEGO Kerberos authentication failed
    

    OID looks like this: 1.2.840.113554.1.2.2

    My MechTypeList looks like this:

    MechTypeList{true false {[1.2.840.48018.1.2.2 1.2.840.113554.1.2.2 1.3.6.1.4.1.311.2.2.30 1.3.6.1.4.1.311.2.2.10] {[] 0} [96 130 6 130 6 9 42 134 72 ***] [] <nil> <nil>} {0 [] [] <nil> <nil>} <nil> <nil>}

    It seems like MechToken comparison failes. What's wrong happens? What can you advice for fix this problem? Let my know if you need some additional information.

  • Encrypting error - trying to use aes256 instead of rc4-hmac

    Encrypting error - trying to use aes256 instead of rc4-hmac

    I am having the same issue as #186 - it is looking for etype 18 (aes256) but I am using 23 (rc4-hmac). I left a comment on that issue but you probably aren't going to see it since it is closed so am opening a new one.

    Here is the full error: Error on AS_REQ: [Root cause: Encrypting_Error] KRBMessage_Handling_Error: AS Exchange Error: failed setting AS_REQ PAData for pre-authentication required < Encrypting_Error: error getting key from credentials: matching key not found in keytab. Looking for [<redacted>] realm: <redacted> kvno: 0 etype: 18

    Here is what is in the keytab: Keytab name: FILE: redacted.keytab KVNO Timestamp Principal 0 06/09/19 10:50:29 redacted@redacted (arcfour-hmac)

    Here are the krb5.conf entries of interest: default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 arcfour-hmac-md5 default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 arcfour-hmac-md5 permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 arcfour-hmac-md5

    I cannot modify the krb5.conf and if I try adding an entry for 18/aes256 (add_entry -password -p redacted@redacted -k 0 -e aes256-cts-hmac-sha1-96) to the keytab, I get an error that says... kinit: Preauthentication failed while getting initial credentials ...and Kerberos doesn't work at all. In my setup, Kerberos only works if there is 1 entry in the keytab and it is the rc4-hmac.

    Is there a way to force gokrb5 to use rc4-hmac instead of aes256 or another way to get things working?

    Note that I am new to Kerberos so apologize if that is a silly question or I am missing something easy.

    Thanks

  • How to use for RFC 3645 GSS-TSIG

    How to use for RFC 3645 GSS-TSIG

    This was alluded to in #58; I'm trying to use this library to be able to perform dynamic DNS updates that are signed using RFC 3645 GSS-TSIG. According to the RFC, the GSSAPI calls I should be using are GSS_Init_sec_context(), GSS_GetMIC() and/or GSS_VerifyMIC(). I can't find these by name in your library but the "Generic Kerberos Client" section in the README seems to read like it's the same flow, particularly the final bit:

    Now send the AP_REQ to the serivce. How this is done will be specific to the application use case.

    This would be (I think) where I send the first TKEY DNS query to the target DNS server. I've captured DNS traffic generated by nsupdate -g and looking at it with Wireshark shows the same; there's a TKEY query that has the ID KRB5_AP_REQ so it looks like my first step is to send that AP_REQ in a DNS query.

    However, I'm not sure what to do about setting the checksum on the authenticator, or is that the equivalent to GSS_VerifyMIC() for the reply(ies) from the server?

    Any pointers appreciated.

  • Error decrypting AP_REQ authenticator: integrity verification failed

    Error decrypting AP_REQ authenticator: integrity verification failed

    Hey,

    Using latest code with an attempt to validate a SPNEGO token sent by an IE11 client: ValidateAPREQ:

    integrity verification failed

    (caused by rfc3961/encryption.go:VerifyIntegrity) it fails on the authenticator decryption part.

    Using osx clients such kinit / chrome works just fine.

    After investigation, the difference is as follows:

    • IE11 sends a MechType.APReq.Ticket.SName.NameType with value 2
    • Curl sends a MechType.APReq.Ticket.SName.NameType with value 3

    This value propagates all the way to rfc3961.DeriveRandom that generates a value that causes DecryptMessage: e.VerifyIntegrity to fail.

    I have workaround this by forcing NameType = 3 that make things work okay, so the code block in ValidateAPREQ is such:

            var creds credentials.Credentials
    	err := APReq.Ticket.DecryptEncPart(kt, sa)
    	if err != nil {
    		return false, creds, krberror.Errorf(err, krberror.DecryptingError, "error decrypting encpart of service ticket provided")
    	}
            // workaround for https://github.com/jcmturner/gokrb5/issues/168
    	APReq.Ticket.SName.NameType = 3
    	a, err := APReq.DecryptAuthenticator(APReq.Ticket.DecryptedEncPart.Key)
    	if err != nil {
    		return false, creds, krberror.Errorf(err, krberror.DecryptingError, "error extracting authenticator")
    	}
    

    Thanks.

    Many thanks.

  • implement GSSAPI MIC token

    implement GSSAPI MIC token

    This hopefully is the last missing piece that finally fixes #65. Based heavily on the Wrap token support added in PR #83.

    I've not documented or added tests yet as currently the intended use for the code doesn't work compared to another existing GSSAPI implementation and I'm not entirely sure if it's my implementation/addition or something wrong with how I'm using the rest of this library. Rather than clutter this PR, I'll keep the discussion in #65 to hopefully work out what's going wrong.

  • Terminate client renewal goroutine if creating new session

    Terminate client renewal goroutine if creating new session

    In Client's updateSession funciton, if renew time passes, we will call ASExchange and it will create a new session. However, the goroutine ran by enableAutoSessionRenewal is still running, when we create a new session we will start another goroutine to call updateSession. Hence, two goroutines will call updateSession. UpdateSession will create more sessions by calling ASExchange, which create new goroutines again. The renewal goroutine grows exponentially, which can cause serious problem. If we call ASExchange to add a new session, the previous goroutine should be terminated.

  • ParseCCache and keytab file

    ParseCCache and keytab file

    Currently, I use

    b, _ := ioutil.ReadFile("krb5cc") // kinit -kt keytab_file [email protected]
    c,_ := credentials.ParseCCache(b)
    cl, _ := client.NewClientFromCCache(c)
    

    this works

    However, instead of using the credential cache I would like to use the keytab directly.

    Is it as simple as swapping

    kt, err := keytab.Load("/path/to/file.keytab")
    cl := client.NewClientWithKeytab("username", "REALM.COM", kt)
    

    or do I have to do more?

    When I tried do it, I get a 401 Unauthorized to my web resource.

    Do I have to anything else? Looking at the code for NewClientFromCCache I see a lot of functions being called -- https://github.com/jcmturner/gokrb5/blob/master/client/client.go#L68, but for NewClientWithKeytab (https://github.com/jcmturner/gokrb5/blob/master/client/client.go#L52), its much smaller.

  • spnego tokens with request flags fail to parse properly

    spnego tokens with request flags fail to parse properly

    gokrb version: 8.3.0 go version: 1.14.3 relevant rfc: rfc2743 section 2.2.1 "req_flags" client library: https://docs.spring.io/spring-security-kerberos/docs/1.0.1.RELEASE/reference/html/ bug demo code: https://pastebin.com/K170JCSR

    When processing SPENGO tokens generated by the Java Spring Kerberos client library I see this error:

    continuation call to routine required

    It turns out that the problem tokens are not being properly parsed such that SPNEGO.NegTokenInit.MechTokenBytes is nil. That misleads spnego into thinking a continuation is needed.

    The parser bug seems to be triggered by the fact that this client library sets request flags. Successful clients don't. When ReqFlags is present the asn1 struct parser fails to properly advance its byte array offset before attempting to parse the next field: MechTokenBytes. That results in the MechTokenBytes field being nil.

    I suspect the issue is in the bit string parsing logic in parseField in github.com/jcmturner/[email protected]/encoding/asn1/asn1.go . I don't know quite enough about how that's supposed to work to attempt a PR though.

    The bug demo code linked to above shows the bug and also shows how to create bug triggering spnego tokens with request flags set.

  • Suggested Improvements to `newAuthenticatorChksum`

    Suggested Improvements to `newAuthenticatorChksum`

    So I was looking at newAuthenticatorChksum, and I suggest improving it like this:

    func newAuthenticatorChksum(flags []int) []byte {
    	a := make([]byte, 24)
    	binary.LittleEndian.PutUint32(a[:4], 16)
    +	f := uint32(0)
    	for _, i := range flags {
    -		if i == gssapi.ContextFlagDeleg {
    -			x := make([]byte, 28-len(a))
    -			a = append(a, x...)
    -		}
    -		f := binary.LittleEndian.Uint32(a[20:24])
    		f |= uint32(i)
    -		binary.LittleEndian.PutUint32(a[20:24], f)
    	}
    +	if f&gssapi.ContextFlagDeleg != 0 {
    +		a = append(a, 0, 0, 0, 0)
    +	}
    +	binary.LittleEndian.PutUint32(a[20:24], f)
     	return a
    }
    

    For me the main benefit is clarity: I think it becomes much more obvious that if gssapi.ContextFlagDeleg is included one or more times in flags, the checksum just gets four zero'd bytes appended to the end.

    You could also see it as an optimization benefit. (Does the compiler realize that the serialization round trip between f and a[20:24] doesn't have to happen each loop? Does the compiler realize that it could possibly save a copy of a copy-on-write page of memory if it waits to write the flag bits until after it knows to extend the checksum slice by four bytes? Well, with these changes it doesn't even have to.)

    (Normally I'd just make a PR with such suggested changes and discuss it there, but your contributing guidelines suggest opening an issue first.)

  • Error authenticating with Kerberos and arcfour-hmac

    Error authenticating with Kerberos and arcfour-hmac

    Hello,

    I'm trying to configure the Redpanda Console to authenticate with my Kafka Broker but, getting some encryption errors.

    I'm using keytabs to authenticate to the Brokers. Currently, I'm using keytabs for Kafka Connect, Kstreams, and ksql.

    All the applications that currently work are Java. Redpanda is the first Go app I'm trying to integrate with Kerberos.

    Using the same krb5.conf that I use for other applications I have the following error:

    {"level":"info","ts":"2022-12-19T09:02:34.332Z","msg":"started Redpanda Console","version":"v2.1.1","built_at":"1669902350"}
    {"level":"info","ts":"2022-12-19T09:02:34.334Z","msg":"connecting to Kafka seed brokers, trying to fetch cluster metadata"}
    {"level":"error","ts":"2022-12-19T09:02:34.347Z","msg":"unable to initialize sasl","source":"kafka_client","broker":"seed 0","err":"could not get valid TGT for client's realm: [Root cause: Encrypting_Error] KRBMessage_Handling_Error: AS Exchange Error: failed setting AS_REQ PAData for pre-authentication required < Encrypting_Error: error getting key from credentials: matching key not found in keytab. Looking for \"<redacted_username>\" realm: <redacted_realm> kvno: 0 etype: 18"}
    {"level":"warn","ts":"2022-12-19T09:02:34.347Z","msg":"Failed to test Kafka connection, going to retry in 1s","remaining_retries":5}
    

    krb5.conf

       [logging]
        default = FILE:/var/log/krb5libs.log
        kdc = FILE:/var/log/krb5kdc.log
        admin_server = FILE:/var/log/kadmind.log
    
        [libdefaults]
        dns_lookup_realm = false
        ticket_lifetime = 10h
        renew_lifetime = 7d
        forwardable = true
        rdns = false
        default_realm = <redacted>
        default_ccache_name = FILE:/tmp/krb5cc_%{uid}
    
        [realms]
        <redacted> = {
          kdc = <redacted>
          kdc = <redacted>
          kdc = <redacted>
          kdc = <redacted>
          admin_server = <redacted>
        }
    
        [domain_realm]
        .<redacted>
    
        # ignore_k5login = true : Never look for a .k5login file in the user's home directory. Instead, only check that the Kerberos principal maps to the local account name.
        [appdefaults]
        pam = {
          <realm> = {
            ignore_k5login = true
          }
        }
    

    Troubleshooting

    I added the Kerberos client to the image and run some kerberos commands to see if the keytab was ok in the Pod:

    /app $ ls
    console
    /app $ klist -ket /keytabs/<redacted>.keytab
    Keytab name: FILE:/keytabs/<redacted>.keytab
    KVNO Timestamp         Principal
    ---- ----------------- --------------------------------------------------------
       1 03/08/21 11:00:58 <redacted_username>@<redacted_realm> (DEPRECATED:arcfour-hmac)
    
    /app $ kinit -fV -k -t /keytabs/<redacted>.keytab <redacted_username>
    Using default cache: /tmp/krb5cc_99
    Using principal: <redacted_username>@<redacted_realm>
    Using keytab: /keytabs/<redacted>.keytab
    Authenticated to Kerberos v5
    

    after reading other issues here, I try to add preferred_preauth_types = 23, default_tkt_enctypes = arcfour-hmac, and default_tgs_enctypes = arcfour-hmac to the `krb5.conf. Now, I have the following error:

    {"level":"error","ts":"2022-12-19T11:04:27.318Z","msg":"unable to initialize sasl","source":"kafka_client","broker":"seed 0","err":"could not get valid TGT for client's realm: [Root cause: Decrypting_Error] KRBMessage_Handling_Error: AS Exchange Error: AS_REP is not valid or client password/keytab incorrect < Decrypting_Error: error decrypting EncPart of AS_REP < Decrypting_Error: error decrypting AS_REP encrypted part: matching key not found in keytab. Looking for [<redacted_username>] realm: <redacted_realm> kvno: 8 etype: 23"}
    

    I see that the kvno for my keytab is 1 and the kvno when using type=23 is 8. Not sure if this has any relation.

    If there is any comments/suggestion in how to proceed from here I really appreciate.

    Thanks!

  • Fix KDCREP verification

    Fix KDCREP verification

    The PR fixes SPNEGO failure when TGS_REP only has IPv4 #500. The original code confirms all IP addresses in TGS_REP and TGS_REQ which fails when TGS_REP only has IPv4 and TGS_REQ had both IPv4 and IPv6.

    The change confirms all IP addresses in TGS_REP are included in TGS_REQ, but not checking the equality.

  • SPNEGO failure when TGS_REP only has IPv4

    SPNEGO failure when TGS_REP only has IPv4

    Issue Summary

    SPNEGO call fails addresses listed in the TGS_REP does not match those listed in the TGS_REQ.

    Environment

    • GoKRB5 v8.4.3
    • Go 1.19.3

    Repro Steps

    • Do this after kinit
    ...
    ccache, err := credentials.LoadCCache('/path/to/ccache')
    cl, err = client.NewFromCCache(ccache, c)
    err = cl.Login()
    r, err := http.NewRequest("GET", url, nil)
    spnegoCl := spnego.NewClient(cl, nil, spn)
    resp, err := spnegoCl.Do(r)
    

    Result

    sage_Handling_Error: addresses listed in the TGS_REP does not match those listed in the TGS_REQ
    

    Expected

    • resp returned successfully by spnegoCl.Do() over SPNEGO

    Root Cause

    When you make an SPNEGO to a KDC, it's possible that tgsReq has 2 x IPv4 + 2 x IPv6 but returned tgsRep only has 2 x IPv4. If it happens, a validation fails at https://github.com/jcmturner/gokrb5/blob/master/messages/KDCRep.go#L298.

    Note

    It doesn't reproduce if you have a service ticket in the credential cache because the root cause is in the validation when talking to KDC.

  • API to get default config/ccache/keytab path

    API to get default config/ccache/keytab path

    The MIT krb5 implementation provides a set of defaults for various values, e.g. port numbers, config file paths and so on. Many of these defaults can be overridden with user-provided environment variables, which is a convenient way to avoid telling each program where their keytabs and credentials caches are placed.

    While it is possible for applications to check all the necessary environment variables and default values themselves, it would probably be much simpler for everyone if the library provided such functionality out of the box. Even better, the library could provide a way to create a "default" client using nothing but these default values.

    To implement this, I suggest adding a pair of functions names GetDefaultPath and LoadDefault (or similar) to each of the following packages: config, keytab, credentials. A default client could be created with a function called NewFromDefaults.

    I understand that the code needs to be platform-agnotic, but I believe that environment variables are ubiquitous enough and the new API should not prevent the library from working on platforms where it's hard to find a default path, as it can simply return an error if it encounters any issues or runs on an unsupported platform.

  • Add support for Wrap Tokens v1

    Add support for Wrap Tokens v1

    This PR:

    • fixes #460
    • enables the fix for https://github.com/Shopify/sarama/issues/2022

    This was tested against life Cloudera Kafka clusters (multiple versions) and everything is working nicely

    I'm not the greatest Go expert, so if there are any issues with the code, let me know & I'd get it fix asap Really kin to get this one merged, so Sarama can also get patched, which in turn would allow other applications in our stack to receive the fix

Ethereum clients monitor
Ethereum clients monitor

e7mon Tool for monitoring your Ethereum clients. Client-agnostic as it queries the standardized JSON-RPC APIs. Requires the following APIs to be expos

Dec 20, 2022
A Prometheus exporter for Ethereum Execution & Consensus clients

?? Ethereum Metrics Exporter ?? A Prometheus metrics exporter for Ethereum execution & consensus nodes Ethereum client implementations expose extensiv

Dec 13, 2022
Pure Go GOST cryptographic functions library.

Pure Go GOST cryptographic functions library. GOST is GOvernment STandard of Russian Federation (and Soviet Union). GOST 28147-89 (RFC 5830) block cip

Aug 10, 2022
Smart.go is a pure Golang library to access disk low-level S.M.A.R.T. information

Smart.go is a pure Golang library to access disk low-level S.M.A.R.T. information. Smart.go tries to match functionality provided by smartctl but with golang API.

Dec 27, 2022
The minilock file encryption system, ported to pure Golang. Includes CLI utilities.
The minilock file encryption system, ported to pure Golang. Includes CLI utilities.

Go-miniLock A pure-Go reimplementation of the miniLock asymmetric encryption system. by Cathal Garvey, Copyright Oct. 2015, proudly licensed under the

Nov 28, 2022
Pure Go implementation of the NaCL set of API's

go-nacl This is a pure Go implementation of the API's available in NaCL: https://nacl.cr.yp.to. Compared with the implementation in golang.org/x/crypt

Dec 16, 2022
Golang interface for local/remote DRM CDM services (NO DRM IMPLEMENTATION HERE)

NO DRM IMPLEMENTATION HERE! ONLY ABSTRAT INTERFACE! What It's a generalized interface for different types of CDM for WEBDL use. A remote CDM JSON-RPC

Oct 24, 2022
This library generate a new tlsconfig usable within go standard library configured with a self-signed certificate generated on the fly

sslcert This library generate a new tlsconfig usable within go standard library configured with a self-signed certificate generated on the fly. Exampl

Dec 17, 2022
This library aims to make it easier to interact with Ethereum through de Go programming language by adding a layer of abstraction through a new client on top of the go-ethereum library.

Simple ethereum client Simple ethereum client aims to make it easier for the developers to interact with Ethereum through a new layer of abstraction t

May 1, 2022
A simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.
A simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.

A simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.

Jan 7, 2023
A convenience library for generating, comparing and inspecting password hashes using the scrypt KDF in Go 🔑

simple-scrypt simple-scrypt provides a convenience wrapper around Go's existing scrypt package that makes it easier to securely derive strong keys ("h

Dec 22, 2022
A Golang cryptocurrency trading API & Library. Support Binance, BitMEX, Deribit, Bybit, Huobi DM, OKEX Futures and more.
A Golang cryptocurrency trading API & Library. Support Binance, BitMEX, Deribit, Bybit, Huobi DM, OKEX Futures and more.

CREX 中文 | English CREX 是一个用Golang语言开发的量化交易库。支持tick级别数字币期货平台的回测和实盘。实盘与回测无缝切换,无需更改代码。 回测 示例 @backtest 交易结果 开源策略 https://github.com/coinrust/trading-stra

Nov 18, 2022
Ethermint is a scalable and interoperable Ethereum library, built on Proof-of-Stake with fast-finality using the Cosmos SDK.
Ethermint is a scalable and interoperable Ethereum library, built on Proof-of-Stake with fast-finality using the Cosmos SDK.

Ethermint Ethermint is a scalable and interoperable Ethereum library, built on Proof-of-Stake with fast-finality using the Cosmos SDK which runs on to

Jan 3, 2023
Port of Google's Keyczar cryptography library to Go

Important note: Keyczar is deprecated. The Keyczar developers recommend Tink. This is a port of Google's Keyczar library to Go. Copyright (c) 2011 Dam

Nov 28, 2022
whirlpool cryptographic hashing library

whirlpool.go A whirlpool hashing library for go Build status Setup $ go get github.com/jzelinskie/whirlpool Example package main import ( "fmt" "

Oct 12, 2022
Golang Library for automatic LetsEncrypt SSL Certificates

Obtains certificates automatically, and manages renewal and hot reload for your Golang application. It uses the LEGO Library to perform ACME challenges, and the mkcert utility to generate self-signed trusted certificates for local development.

Dec 23, 2022
:key: Idiotproof golang password validation library inspired by Python's passlib

passlib for go 100% modules-free. Python's passlib is quite an amazing library. I'm not sure there's a password library in existence with more thought

Dec 19, 2022
Easy to use encryption library for Go

encryptedbox EncryptedBox is an easy to use module for Go that can encrypt or sign any type of data. It is especially useful when you must serialize y

Jul 20, 2022
A Go library to create hashes with a builtin expiration

ExpiringLink This is a simple library for creating unique strings that have a built in expiration. The target use case is web links for password reset

Mar 3, 2022