package com.airbnb.chancery.github; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Hex; import javax.annotation.Nullable; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.validation.constraints.NotNull; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; @Slf4j public final class GithubAuthChecker { static final String HMAC_SHA1 = "HmacSHA1"; final Mac mac; public GithubAuthChecker(String secret) throws NoSuchAlgorithmException, InvalidKeyException { mac = Mac.getInstance(HMAC_SHA1); final SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(), HMAC_SHA1); mac.init(signingKey); } /** * Checks a github signature against its payload * @param signature A X-Hub-Signature header value ("sha1=[...]") * @param payload The signed HTTP request body * @return Whether the signature is correct for the checker's secret */ public boolean checkSignature(@Nullable String signature, @NotNull String payload) { if (signature == null || signature.length() != 45) return false; final char[] hash = Hex.encodeHex(this.mac.doFinal(payload.getBytes())); final StringBuilder builder = new StringBuilder("sha1="); builder.append(hash); final String expected = builder.toString(); log.debug("Comparing {} and {}", expected, signature); return expected.equals(signature); } }