Zsh, 94 9487 bytes
Edit: Lost 3 bytes to fix a bug (if first key is backspace, a[1]= makes $a an array). Saved 3 bytes by not using %s in the printf statement, then 7 more by switching from while to for.
a= whilefor (($#a<4;$#a<4;)); do {read -sk1 k case $k {$'\C-?')a[1]=;;[0-9])a+=*;} printf '\r\e[K'$a done} asterisks= # $#foo: length of $foo whilefor (($#asterisks;$#asterisks < 44;)); do{ # -s: silent/noecho, -k 1: one keypress read -s -k 1 key case $key { # backspace: delete first character from asterisks string $'\C-?') asterisks[1]= ;; [0-9]) asterisks+=* } # \r: start of line, \e[K: clear to end of line printf '\r\e[K'$asterisks done}